I just started with C# a week ago (programming with C++ like 2 1/2 years) and today I started my first form application. It is just a simple calculator.
So I have a form with the buttons 0-9; + ;- ;*;/ (and some more but they are not interesting for this problem) and one multiple line textbox. If the user press a button the specific symbol or digit is written directly to the output textbox. So the input part is working fine.
The problem is the calculation part. The code for this part is:
DataTable dt = new DataTable();
double result = (double)dt.Compute(output.Text.ToString(), "");
output.AppendText($" ={result.ToString()}");
If I run it I'm getting this error:
*System.InvalidCastException
HResult=0x80004002
Message=Specified cast is not valid.
Source=SimpleCalculator
StackTrace:
at SimpleCalculator.Form1.result_Click(Object sender, EventArgs e) in C:\Users\Max\Documents\C#\Projects\SimpleCalculator\SimpleCalculator\Form1.cs:line 105
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at SimpleCalculator.Program.Main() in*
So the interesting thing is ill changed it to int 32 (what's the error message is saying)
double result = (int32)dt.Compute(output.Text.ToString(), "");
it works fine until double values then it runs to an error (what is logic) but if I change it back to double its working.
double result = (double)dt.Compute(output.Text.ToString(), "");
I'm a bit confused about this because I didn't change anything in the code and the error comes sometimes back.
I mean yeah its working but not clean enough for me. I want to have an code without any chance to run to an error.
I'm using Visual Studio 2017 Community, is it because of VB or because of bad code?
You may use the Convert class instead of casting. Example:
double result = Convert.ToDouble(dt.Compute(output.Text.ToString(), ""));
You need to use double
. DataTable.Compute
supports multiple operators and the result sometimes is an integer and sometimes a double
. So use the greater type that works with always: double
.
This returns int
:
new DataTable().Compute("1+1", null) // 2 int
and this returns double
:
new DataTable().Compute("1/1", null) // 1.0 double
You can use System.Convert.To.Double
:
System.Convert.ToDouble(new DataTable().Compute("1+1", null));
Operators, rules and syntax is explained here
I know about the syntax of this function, that's not the problem; this error only occurs sometimes (by integer returns too).
I'll try now kaffekopps resolution and accept his answer. If the error comes back I'll reopen this question.
You are getting error because Datatable.Compute returns Object which contains text.
In C#, casting Text to Number wont compile because compiler cant convert text to number. Text may not contain only numbers but any character. You will have to use Convert.To()
If you are interested into this problematic you can read question about difference between casting and using Convert.
In you code, if you change line
double result = (double)dt.Compute(output.Text.ToString(), "");
into
double result = Convert.ToDouble(dt.Compute(output.Text.ToString(), ""));
it should works fine.
User contributions licensed under CC BY-SA 3.0