Int.Parse из "8" не удается. int.Parse всегда требует CultureInfo.InvariantCulture? - PullRequest
11 голосов
/ 27 апреля 2010

Мы разрабатываем установленное программное обеспечение, которое отлично работает на всех известных компьютерах, кроме одного.Проблема в том, чтобы разобрать строки, которые начинаются с "8". Кажется, что "8" в начале строки является зарезервированным символом.

Parsing:
int.Parse("8") -> Exception message: Input string was not in a correct format. 
int.Parse("80") -> 0
int.Parse("88") -> 8
int.Parse("8100") -> 100

CurrentCulture: sv-SE 
CurrentUICulture: en-US

Проблема решается с помощью int.Parse ("8", CultureInfo.InvariantCulture) .Однако было бы неплохо узнать источник проблемы.

Вопрос: Почему мы получаем такое поведение «8», если мы не указываем инвариантную культуру?


Дополнительная информация:

Я отправил небольшую программу своему клиенту для достижения указанного выше результата:

    private int ParseInt(string s)
    {
        int parsedInt = -1000;
        try
        {
            parsedInt = int.Parse(s);

            textBoxMessage.Text = "Success: " + parsedInt;

        }
        catch (Exception ex)
        {
            textBoxMessage.Text =
                string.Format("Error parsing string: '{0}'", s) + Environment.NewLine +
                "Exception message: " + ex.Message;
        }

        textBoxMessage.Text += Environment.NewLine + Environment.NewLine +
            "CurrentCulture: " + Thread.CurrentThread.CurrentCulture.Name + "\r\n" +
            "CurrentUICulture: " + Thread.CurrentThread.CurrentUICulture.Name + "\r\n";
        return parsedInt;
    }

Обновление

Я наткнулся на эту ссылку, ошибка в базе данных Microsoft Connect:

https://connect.microsoft.com/VisualStudio/feedback/details/253265/int32-parse-fails-to-convert-the-string-0-zero-on-some-systems

Кажется, что есть проблема с похожими симптомами, нонет настоящей коренной причины.Если бы кто-нибудь мог уточнить это, я был бы признателен!

1 Ответ

21 голосов
/ 27 апреля 2010

Для культуры sv-SE 8 представляет CurrencyNegativePattern, и именно поэтому вы получаете ошибку, которую вы описали.

Вы можете проверить это, запустив следующий пример:

var ci = new CultureInfo("sv-SE");

var nfi = (NumberFormatInfo)ci.GetFormat(typeof(NumberFormatInfo));

Console.WriteLine(nfi.CurrencyNegativePattern);
Console.WriteLine(nfi.CurrencyPositivePattern);

Будет выведено:

// 8
// 3

Вы можете явно сказать, что вы анализируете целое число, а не валюту, используя перегрузку Parse, которая принимает перечисление NumberStyles.

Int32.Parse("8", NumberStyles.Integer, new CultureInfo("sv-SE"));

На этот раз, так как вы указываете, что анализируете целое число, ошибки не будет.


Тем не менее, IIRC Int32.Parse должен интерпретировать входные данные как целое число по умолчанию, поэтому я не понимаю, почему вы получаете ошибку с этим примером кода.


Обновление:

Из информации, которую вы недавно добавили, кажется, что вы должны убедиться, что проблема не является внешней. Это если, например, пользователь изменил настройку положительного знака языкового стандарта Windows на 8, это было бы нормально и имело бы смысл для вас получить ошибку, которую вы получаете. Это все равно что установить + в качестве положительного знака, а затем попытаться разобрать его:

var ci = new CultureInfo("sv-SE");
var nfi = (NumberFormatInfo)ci.GetFormat(typeof(NumberFormatInfo));

nfi.PositiveSign = "+";

Int32.Parse("+", nfi); // This will throw

Попросите пользователя указать его настройки реестра, как указано в проблеме с подключением, и убедитесь, что они соответствуют вашим ожиданиям.

Примечание: Добро пожаловать в SO, и, кстати, в следующий раз, когда вам нужно будет добавить дополнительную информацию к вашему вопросу, вы должны отредактировать ее, а не предоставлять ее в ответе.

...