Int.Parse of "8" терпит неудачу. int.Parse всегда требует CultureInfo.InvariantCulture?

Мы разрабатываем установленное программное обеспечение, которое отлично работает на всех известных компьютерах, кроме одного. Проблема состоит в том, чтобы проанализировать строки, начинающиеся с "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

Для культуры 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 должен интерпретировать ввод как целое по умолчанию, поэтому почему вы попадаете на ошибку с этим примером кода вне меня.


Update:

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

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

nfi.PositiveSign = "+";

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

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

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