Подтвердить что ты не робот

Инвариант культуры Decimal.TryParse()

Я пишу настраиваемую строку для десятичного валидатора, которая должна использовать Decimal.TryParse, который игнорирует культуру (т.е. не имеет значения, содержит ли вход "." или "," как разделитель десятичной точки). Это предложенный метод:

public static bool TryParse(
    string s,
    NumberStyles style,
    IFormatProvider provider,
    out decimal result
)

Я не могу понять, что использовать в качестве третьего параметра. Примеры, которые я видел, выглядят следующим образом:

culture = CultureInfo.CreateSpecificCulture("en-GB");
Decimal.TryParse(value, style, culture, out number)

чтобы создать определенную культуру. CultureInfo не имеет метода CreateInvariantCulture и CultureInfo.InvariantCulture не является требуемым типом. Какое правильное использование?

4b9b3361

Ответ 1

Попробуйте вот так:

decimal value;
bool b = Decimal.TryParse("0.1", NumberStyles.Any, new CultureInfo("en-US"), out value);

Лучшим способом, вероятно, будет использование метода Decimal.Parse(), как и традиционно с любыми значениями десятичной строки.

Вы можете использовать NumberStyles.Currency, чтобы указать, что значения должны считываться как валюта, которая будет учитывать любые значения, связанные с валютой (вам нужно будет добавить ссылку на System.Globalalization, чтобы использовать это:

using System.Globalization;

Decimal.Parse также принимает третий параметр, который позволит вам явно установить IFormatProvider, если вы так пожелаете, и пожелаете вам определенной культуры:

decimal value = Decimal.Parse(currency, NumberStyles.Currency, CultureInfo.InvariantCulture); //yields 15.55

Ответ 2

Мои плохие парни. Я проверил следующий код:

        string DutchDecimal = "1,5";
        string EnglishDecimal = "1.5";
        decimal a;
        decimal b;
        Console.WriteLine(decimal.TryParse(DutchDecimal, out a));
        Console.WriteLine(a);
        Console.WriteLine(decimal.TryParse(EnglishDecimal, out b));
        Console.WriteLine(b);
        Console.Read();

и он правильно разбирает обе строки. Похоже, что по умолчанию TryParse действительно является инвариантом для культуры. Я предположил, что это не так, потому что стандартный TypeConversionValidator в EnterpriseLibrary был зависимым от культуры, и я предположил, что он просто использовал TryParse. Однако, как оказалось, этот синтаксический анализатор по умолчанию жестко запрограммирован для использования текущей культуры.

EDIT: я выяснил, что "1,5" преобразуется в 1,5 и "1,5" преобразуется в 15. Это действительно правильно для поведения, связанного с культурой, так что это так. Весь этот вопрос, по-видимому, породил мое непонимание того, как работает инвариант культуры.

Ответ 3

Фактически CultureInfo.InvariantCulture можно использовать здесь. Параметр ожидает IFormatProvider, интерфейс, который реализует CultureInfo. Но InvariantCulture является инвариантным в том смысле, что он не зависит от пользовательских настроек.

На самом деле нет культуры, которая принимает либо ,, либо . как десятичный разделитель - они все одно или другое. Вам нужно будет найти другой способ обработки данных, которые могут использовать любой из этих разделителей.

Ответ 4

Я не могу понять, что использовать в качестве третьего параметра.

Потому что все культуры NumberDecimalSeparator или NumberGroupSeparator и т.д. не совпадают.

Кто-то использует . как NumberDecimalSeparator, кто-то использует ,, но нет CultureInfo, который использует оба как NumberDecimalSeparator.

CultureInfo реализует IFormatProvider интерфейс. Поэтому, если вы укажете свой CultureInfo, ваша строка value попытается проанализировать эти правила культур.

Я пишу пользовательскую строку в десятичный валидатор, который должен использовать Decimal.TryParse, игнорирующий культуру

В этом случае вы можете использовать метод CultureInfo.Clone для копирования какой культуры вы хотите (или InvariantCulture), и вы можете установить NumberDecimalSeparator и NumberGroupSeparator, какую строку вы хотите.