C# Form 文本框字符串计算与数据表()
C# Form Textbox string calculation with datatable()
我一周前才开始使用 C#(使用 C++ 编程大约 2 1/2 年),今天我开始了我的第一个表单应用程序。它只是一个简单的计算器。
所以我有一个带有按钮 0-9 的表单; + ;- ;*;/ (还有一些,但它们对这个问题不感兴趣)和一个多行文本框。如果用户按下按钮,特定符号或数字将直接写入输出文本框。所以输入部分工作正常。
问题出在计算部分。这部分的代码是:
DataTable dt = new DataTable();
double result = (double)dt.Compute(output.Text.ToString(), "");
output.AppendText($" ={result.ToString()}");
如果我运行它我得到这个错误:
*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*
所以有趣的是我把它改成了 int 32(错误信息说的是什么)
double result = (int32)dt.Compute(output.Text.ToString(), "");
它工作正常,直到双值然后它 运行s 出错(什么是逻辑)但是如果我将它改回两倍它的工作。
double result = (double)dt.Compute(output.Text.ToString(), "");
我对此有点困惑,因为我没有更改代码中的任何内容,但错误有时会再次出现。
我的意思是是的,它可以工作,但对我来说不够干净。我想要一个没有任何机会 运行 错误的代码。
我正在使用 Visual Studio 2017 社区,是因为 VB 还是因为代码错误?
您可以使用 Convert class 而不是转换。示例:
double result = Convert.ToDouble(dt.Compute(output.Text.ToString(), ""));
您需要使用 double
。 DataTable.Compute
支持多个运算符,结果有时是整数,有时是 double
。因此,请使用始终适用的更大类型:double
.
这个returnsint
:
new DataTable().Compute("1+1", null) // 2 int
和这个 returns double
:
new DataTable().Compute("1/1", null) // 1.0 double
您可以使用 System.Convert.To.Double
:
System.Convert.ToDouble(new DataTable().Compute("1+1", null));
运算符、规则和语法解释 here
我知道这个函数的语法,那不是问题;此错误仅有时发生(也是整数 returns)。
我现在将尝试使用 kaffekopps 解决方案并接受他的回答。如果错误再次出现,我会重新打开这个问题。
您遇到错误,因为 Datatable.Compute returns 包含文本的对象。
在 C# 中,将文本转换为数字不会编译,因为编译器无法将文本转换为数字。文本可能不仅包含数字,还包含任何字符。您将不得不使用 Convert.To()
如果您对这个问题感兴趣,可以阅读 question 转换和使用 Convert 之间的区别。
在你的代码中,如果你改变行
double result = (double)dt.Compute(output.Text.ToString(), "");
进入
double result = Convert.ToDouble(dt.Compute(output.Text.ToString(), ""));
应该没问题。
我一周前才开始使用 C#(使用 C++ 编程大约 2 1/2 年),今天我开始了我的第一个表单应用程序。它只是一个简单的计算器。
所以我有一个带有按钮 0-9 的表单; + ;- ;*;/ (还有一些,但它们对这个问题不感兴趣)和一个多行文本框。如果用户按下按钮,特定符号或数字将直接写入输出文本框。所以输入部分工作正常。
问题出在计算部分。这部分的代码是:
DataTable dt = new DataTable();
double result = (double)dt.Compute(output.Text.ToString(), "");
output.AppendText($" ={result.ToString()}");
如果我运行它我得到这个错误:
*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*
所以有趣的是我把它改成了 int 32(错误信息说的是什么)
double result = (int32)dt.Compute(output.Text.ToString(), "");
它工作正常,直到双值然后它 运行s 出错(什么是逻辑)但是如果我将它改回两倍它的工作。
double result = (double)dt.Compute(output.Text.ToString(), "");
我对此有点困惑,因为我没有更改代码中的任何内容,但错误有时会再次出现。
我的意思是是的,它可以工作,但对我来说不够干净。我想要一个没有任何机会 运行 错误的代码。
我正在使用 Visual Studio 2017 社区,是因为 VB 还是因为代码错误?
您可以使用 Convert class 而不是转换。示例:
double result = Convert.ToDouble(dt.Compute(output.Text.ToString(), ""));
您需要使用 double
。 DataTable.Compute
支持多个运算符,结果有时是整数,有时是 double
。因此,请使用始终适用的更大类型:double
.
这个returnsint
:
new DataTable().Compute("1+1", null) // 2 int
和这个 returns double
:
new DataTable().Compute("1/1", null) // 1.0 double
您可以使用 System.Convert.To.Double
:
System.Convert.ToDouble(new DataTable().Compute("1+1", null));
运算符、规则和语法解释 here
我知道这个函数的语法,那不是问题;此错误仅有时发生(也是整数 returns)。
我现在将尝试使用 kaffekopps 解决方案并接受他的回答。如果错误再次出现,我会重新打开这个问题。
您遇到错误,因为 Datatable.Compute returns 包含文本的对象。
在 C# 中,将文本转换为数字不会编译,因为编译器无法将文本转换为数字。文本可能不仅包含数字,还包含任何字符。您将不得不使用 Convert.To()
如果您对这个问题感兴趣,可以阅读 question 转换和使用 Convert 之间的区别。
在你的代码中,如果你改变行
double result = (double)dt.Compute(output.Text.ToString(), "");
进入
double result = Convert.ToDouble(dt.Compute(output.Text.ToString(), ""));
应该没问题。