Вычисление строки текстового поля формы С# с помощью 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(), "");

он отлично работает до двойных значений, затем он работает с ошибкой (что такое логика), но если я верну его обратно, чтобы удвоить его работу.

double result = (double)dt.Compute(output.Text.ToString(), "");

Я немного смущен этим, потому что я ничего не менял в коде, и ошибка иногда возвращается.

Я имею в виду, да, это работает, но недостаточно чисто для меня. Я хочу иметь код без каких-либо шансов на ошибку.

Я использую сообщество Visual Studio 2017, это из-за VB или из-за плохого кода?


person Max    schedule 08.10.2018    source источник
comment
Что вы подразумеваете под ВБ?   -  person Tim Schmelter    schedule 08.10.2018
comment
Извините, опечатки VS (Visual Studio)   -  person Max    schedule 08.10.2018
comment
Почему нельзя использовать double? Если вычисление иногда возвращает целые числа, а иногда удваивается, используйте double, потому что это работает для обоих. 1+1=2 возвращает int, а 1/1=1.0 возвращает double   -  person Tim Schmelter    schedule 08.10.2018
comment
Я новичок в Visual Studio (для С++ я использую QT Creator), где я могу отладить специальную строку кода? PS: Сейчас он снова работает, я не понимаю, почему это появляется только иногда, ничего не меняя в этой функции.   -  person Max    schedule 08.10.2018
comment
например в окне быстрого просмотра. Но посмотрите на мой отредактированный комментарий, вы видите, что вам нужен double, потому что он обрабатывает все вычисления.   -  person Tim Schmelter    schedule 08.10.2018
comment
Я использую double, но вы видите в сообщении об ошибке, что ему нужен тип int32, и как я сказал, что это работает, но если я получаю двойное значение, конечно, int32 выдает ошибку. Ошибка с двойником - это длинное сообщение об ошибке, которое появляется только иногда, но на самом деле раздражает меня.   -  person Max    schedule 08.10.2018
comment
Я использую этот код: DataTable dt = new DataTable(); двойной результат = (двойной)dt.Compute(output.Text.ToString(), ); строка newout = результат.ToString(); Я использую двойники, но иногда это приводит к этой ошибке сверху, и я не знаю, почему.   -  person Max    schedule 08.10.2018


Ответы (4)


Вы можете использовать Convert класс вместо кастинга. Пример:

double result = Convert.ToDouble(dt.Compute(output.Text.ToString(), ""));
person kaffekopp    schedule 08.10.2018

Вам нужно использовать double. DataTable.Compute поддерживает несколько операторов, и иногда результатом является целое число, а иногда — double. Поэтому используйте больший тип, который работает всегда: double.

Это возвращает int:

new DataTable().Compute("1+1", null)  // 2 int

и это возвращает double:

new DataTable().Compute("1/1", null) // 1.0 double

Вы можете использовать System.Convert.To.Double:

System.Convert.ToDouble(new DataTable().Compute("1+1", null));

Объясняются операторы, правила и синтаксис здесь

person Tim Schmelter    schedule 08.10.2018

Вы получаете сообщение об ошибке, поскольку Datatable.Compute возвращает объект, содержащий текст. В C# преобразование текста в число не будет компилироваться, потому что компилятор не может преобразовать текст в число. Текст может содержать не только цифры, но и любой символ. Вам придется использовать Convert.To()

Если вас интересует эта проблема, вы можете прочитать вопрос о разнице между кастингом и использованием Convert.

В вашем коде, если вы измените строку

 double result = (double)dt.Compute(output.Text.ToString(), "");

в

 double result = Convert.ToDouble(dt.Compute(output.Text.ToString(), ""));

он должен работать нормально.

person Kamil Folwarczny    schedule 08.10.2018

Я знаю о синтаксисе этой функции, это не проблема; эта ошибка возникает только иногда (в том числе и при целочисленном возврате).

Сейчас я попробую разрешение кофекопса и приму его ответ. Если ошибка вернется, я снова открою этот вопрос.

person Max    schedule 08.10.2018