Decimal.Parse выдает FormatException

Я попытался использовать decimal.parse, как описано в: http://msdn.microsoft.com/en-us/library/cafs243z%28v=vs.110%29.aspx

Итак, я скопировал с этой страницы следующий пример:

   string value;
   decimal number;
   value = "1.62345e-02";
   try
   {
       number = Decimal.Parse(value);
       Console.WriteLine("'{0}' converted to {1}.", value, number);
   }
   catch (FormatException)
   {
       Console.WriteLine("Unable to parse '{0}'.", value);
   }

И я получил FormatException. У вас есть идея, почему это произошло?

спасибо, эял


person Eyal leshem    schedule 12.05.2014    source источник
comment
Неправильный языковой стандарт для потока, ожидающий вместо .???   -  person TomTom    schedule 12.05.2014
comment
укажите CultureInfo в Parse.   -  person Xaruth    schedule 12.05.2014
comment
Я почти уверен, что Decimal.Parse не обрабатывает нотацию e по умолчанию - документация, из которой вы скопировали это, даже говорит вам, что это не сработает.   -  person Steve Pettifer    schedule 12.05.2014


Ответы (2)


Попробуй это:

using System.Globalization;
using System.Text;

....

number = Decimal.Parse(value, NumberStyles.AllowExponent|NumberStyles.AllowDecimalPoint);

Чтобы проанализировать число в экспоненциальном формате, вам необходимо установить соответствующие флаги из NumberStyles Enumeration, как описано здесь.

person shree.pat18    schedule 12.05.2014

ответ shree.pat18, конечно, правильный. Но я хочу объяснить этот вопрос немного больше, если вы позволите мне..

Давайте посмотрим, как Decimal.ToParse(string) метод реализовано;

public static Decimal Parse(String s)
{
   return Number.ParseDecimal(s, NumberStyles.Number, NumberFormatInfo.CurrentInfo);
}

Как видите, этот метод использует NumberStyles.Number По умолчанию. Это стиль составных чисел, и он реализован подобно;

Number   = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign | AllowTrailingSign |
           AllowDecimalPoint | AllowThousands,

Это означает, что ваша строка может иметь один из;

Поскольку NumberStyles.Number имеет AllowDecimalPoint, он соответствует . в вашей строке, но этот стиль не имеет AllowExponent, поэтому он не может проанализировать e-02 в вашей строке.

Вот почему вам нужно использовать Decimal.Parse Method (String, NumberStyles) перегрузку так как вы можете указать NumberStyles самостоятельно.

person Soner Gönül    schedule 12.05.2014
comment
Спасибо @SergeyBerezovskiy Я пытаюсь научить его ловить рыбу, а не давать ему рыбу. - person Soner Gönül; 12.05.2014
comment
В большинстве случаев (например, при вводе из файлов) вы также захотите использовать NumberFormatInfo.InvariantInfo, то есть использовать перегрузку Parse(String, NumberStyles, IFormatProvider). Независимо от того, хотите ли вы использовать системную культуру или инвариантную культуру, лучше быть конкретным и передать аргумент NumberFormatInfo. Следующий разработчик может сразу увидеть, какой формат десятичных знаков и т. д. ожидается. - person Anders Forsgren; 12.05.2014
comment
@AndersForsgren К сожалению, OP никогда не говорил, что именно использует его CurrentCulture. Вот почему я предполагаю, что его культура использует . как NumberDecimalSeparator его текущей культуры. У вас есть мнение, что использование IFormatProvider в большинстве случаев будет более понятным. Но InvariantInfo не зависит от культуры. Он использует InvariantCulture настройки. Вот почему всегда использовать InvariantInfo может быть не очень хорошей идеей. Конечно, все это зависит от исходных данных. - person Soner Gönül; 12.05.2014
comment
+1 за подробный ответ и неявный +1 за лежащую в его основе философию. - person shree.pat18; 12.05.2014
comment
@SonerGönül Я согласен, что нам нужно больше деталей здесь, но, тем не менее, хорошо быть явным: я рекомендую передавать CurrentCulture, даже если это эквивалентно пропуску аргумента. Что касается текущего и инвариантного, я считаю, что 99% ошибок (почти еженедельно, так как я работаю в культуре с десятичной запятой) связаны с кодом, который не думал об этом и использовал значение по умолчанию (системная культура), несмотря на то, что они имели в виду. должен был использовать InvariantCulture. Противоположный вид бага я почти никогда не видел! - person Anders Forsgren; 12.05.2014
comment
@AndersForsgren Если вы так говорите :) - person Soner Gönül; 13.05.2014