Рейтинг:
18
BillWoodruff
Для этого вам придется сканировать текстовое поле, создавать числовые значения и писать код для выполнения арифметических функций. Другими словами, вы должны написать a синтаксический анализатор- Это не так просто !
Однако, для простой числовые выражения, вы можете использовать функцию ' Compute объекта DataTable: [^]
// required along with the other usual references
using System.Data;
// in some method
var result = new DataTable().Compute(yourTextBox.Text, null);
Но подумайте хорошенько, хорошая это идея или нет: любая ошибка в вводе текстового поля приведет к сбою при вызове функции "вычислить". Функция "вычислить" возвращает объект, который вам нужно будет преобразовать в правильный тип для использования
в виде числа.
Если вы новичок в .NET, я призываю вас сосредоточиться на основах, а не на таком коде, как этот, который является своего рода взломом !
Но, если вы должны использовать его, давайте покажем правильный пример;
private DataTable dTable = new DataTable();
public double? EvalText(string text)
{
object result = null;
try
{
result = dTable.Compute(text, null);
if (result == null) return null;
return Convert.ToDouble(result);
}
catch (Exception ex)
{
throw new ArgumentException($"{text} cannot be parsed to return double : Exception {ex.Message}", ex.InnerException);
}
}
Пример использования:
private void yourButton_Click(object sender, EventArgs e)
{
double? result = EvalText(yourTextBox.Text);
if(result != null)
{
// valid result
}
}
Зачем использовать "двойной"? Потому что любой другой числовой тип может быть преобразован в 'Double.
Richard Deeming
Любое другое здравомыслящий числовой тип может быть преобразован в double
. :)
Технически, BigInteger[^]- это числовой тип, и он может представлять значения, которые не могут поместиться в double
Попытка преобразовать их приведет к ответу: бесконечность[^].
Кроме того, не совсем понятно, почему вы ловите все исключения в EvalText
, просто чтобы бросить другое исключение? Я бы ожидал, что он либо поймает и проглотит конкретные "ожидаемые" исключения, вызванные неверным пользовательским вводом, либо позволит исходному исключению распространяться, поскольку оно будет содержать дополнительную информацию. По крайней мере, я ожидал бы увидеть исходное исключение, используемое в качестве внутреннего исключения нового исключения, которое вы бросаете.
BillWoodruff
Всегда рад получить от вас ответ !
1. большое целое число ... "разумный" тип: я думаю, что мы находимся на другой стороне Галактики от большого целого числа в этом контексте :) и у вас нет возможности указать какие-либо ограничения типа, используя ограниченные возможности DataTable.Вычислять
2. исключение afaik System.Data.SyntaxErrorException является наиболее вероятным исключением, вызванным DataTable.Ошибка вычисления: я просто помещаю некоторую дополнительную информацию в его выходные данные. к вашему сведению: попробуйте сделать это на строке, которая приведет к переполнению при преобразовании другими способами, и вы можете получить ошибку переполнения, но imho это вряд ли имеет значение здесь.
Richard Deeming
Меня больше беспокоило то, что ты ... выбрасывание в противном случае полезная информация, не включающая реальное исключение в качестве внутреннего исключения того, которое вы бросаете. :)
catch (Exception ex)
{
throw new System.Data.SyntaxErrorException($"invalid data: {text} cannot be parsed", ex);
}
Раздражающе,
документация для DataTable.Compute
[
^] не перечисляет исключений, которые он может выбросить. Глядя на
источник[
^], это похоже на начало глубокой кроличьей норы кода, так что это не простая задача, чтобы выяснить, что может пойти не так.
BillWoodruff
Привет, Ричард, Да, этот пример обработки ошибок небрежен: я изменил код, чтобы использовать тот вид обработки ошибок, который я бы использовал для производственного кода, где есть один явный источник ошибок:
поймать (исключение бывший)
{
throw new ArgumentException($"{text} не может быть проанализирован для возврата double : Exception {ex.Message}", ex.InnerException);
}
Я никогда не использовал DataTable.Вычислить себя ... до сих пор, и если бы я когда-нибудь использовал его, я бы использовал его с подклассовым текстовым полем, которое ограничивало ввод набором "законных" символов.
спасибо, Билл
Richard MacCutchan
Я сомневаюсь, что ОП смог бы понять хоть одно слово из этого. Вопрос, очевидно, является школьным заданием, и есть вероятность, что он просто хочет сложить два целых числа вместе. Таким образом, очевидный ответ заключается в использовании Int.TryParse для получения значений и ToString для получения ответа в виде текста. Использование двойных типов для такого рода задач-плохая идея из-за проблем точности с поплавками и двойниками.
BillWoodruff
Привет, Ричард, я согласен с твоей оценкой вероятной ситуации и состояния операции :) И я ясно выражаю свое двойственное отношение к использованию этой техники и ее ограничениям.
Мое обоснование для ответа-это идея, что она может быть в какой-то момент полезна кому-то на CP. И для меня ценность ответа-это диалог, который у меня был с Ричардом Димингом.
твое здоровье, Билл