Есть ли способ сделать функции С# TryParse()
немного более строгими?
Прямо сейчас, если вы передаете строку, содержащую числа, правильные десятичные и тысячи разделительных символов, она часто кажется, что их принимают, даже если формат не имеет смысла, например: 123''345'678
Я ищу способ сделать TryParse
не успешным, если число не в нужном формате.
Итак, я нахожусь в Цюрихе, и если я это сделаю:
decimal exampleNumber = 1234567.89m;
Trace.WriteLine(string.Format("Value {0} gets formatted as: \"{1:N}\"", exampleNumber, exampleNumber));
... тогда, с моими региональными настройками, я получаю это...
Value 1234567.89 gets formatted as: "1'234'567.89"
Итак, вы можете видеть, что для моей области знак десятичной точки является полной остановкой, а тысячный разделитель - апострофом.
Теперь давайте создадим простую функцию, чтобы проверить, можно ли анализировать string
в decimal
:
private void ParseTest(string str)
{
decimal val = 0;
if (decimal.TryParse(str, out val))
Trace.WriteLine(string.Format("Parsed \"{0}\" as {1}", str, val));
else
Trace.WriteLine(string.Format("Couldn't parse: \"{0}\"", str));
}
Хорошо, позвольте этой функции вывести несколько строк.
Какую из следующих строк вы считаете успешной обработкой этой функции?
Ниже приведены результаты, полученные мной:
ParseTest("123345.67"); // 1. Parsed "123345.67" as 123345.67
ParseTest("123'345.67"); // 2. Parsed "123'345.67" as 123345.67
ParseTest("123'345'6.78"); // 3. Parsed "123'345'6.78" as 1233456.78
ParseTest("1''23'345'678"); // 4. Parsed "1''23'345'678" as 123345678
ParseTest("'1''23'345'678"); // 5. Couldn't parse: "'1''23'345'678"
ParseTest("123''345'678"); // 6. Parsed "123''345'678" as 123345678
ParseTest("123'4'5'6.7.89"); // 7. Couldn't parse: "123'4'5'6.7.89"
ParseTest("'12'3'45'678"); // 8. Couldn't parse: "'12'3'45'678"
Я думаю, вы можете видеть мою мысль.
Мне нужны только первые две строки. Остальные должны были потерпеть неудачу, так как они не имеют 3-значных цифр после тысячи разделителей или имеют два апострофа вместе.
Даже если я изменю ParseTest
, чтобы быть более конкретным, результаты будут точно такими же. (Например, он с радостью принимает "123''345'678
" как допустимое десятичное число.)
private void ParseTest(string str)
{
decimal val = 0;
var styles = (NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands);
if (decimal.TryParse(str, styles, CultureInfo.CurrentCulture, out val))
Trace.WriteLine(string.Format("Parsed \"{0}\" as {1}", str, val));
else
Trace.WriteLine(string.Format("Couldn't parse: \"{0}\"", str));
}
Итак, есть ли простой способ не допускать принятие отформатированных строк с помощью TryParse
?
Обновление
Спасибо за все предложения.
Возможно, я должен уточнить: то, что я ищу, - это то, что первые две из этих строк являются действительными, а третье - для отклонения.
ParseTest("123345.67");
ParseTest("123'456.67");
ParseTest("12'345'6.7");
Конечно, должен быть способ использовать "NumberStyles.AllowThousands
", поэтому он может дополнительно разрешить тысячи разделителей, но убедиться, что формат номера имеет смысл?
Прямо сейчас, если я использую это:
if (decimal.TryParse(str, styles, CultureInfo.CurrentCulture, out val))
Получаю следующие результаты:
Parsed "123345.67" as 123345.67
Parsed "123'456.67" as 123456.67
Parsed "12'345'6.7" as 123456.7
И если я использую это:
if (decimal.TryParse(str, styles, CultureInfo.InvariantCulture, out val))
Получаю следующие результаты:
Parsed "123345.67" as 123345.67
Couldn't parse: "123'456.67"
Couldn't parse: "12'345'6.7"
Это моя проблема... независимо от настроек CultureInfo, эта третья строка должна быть отклонена, а первые два приняты.