Разбор чисел из разных культур в C # - PullRequest
4 голосов
/ 18 января 2012

Я пишу некоторый код для разбора строки в double, но эта строка передается мне с другого компьютера. Естественно, возникла проблема, когда культура может отличаться. Итак, пока машина А может отправить мне:

"0.5"

Машина B может отправить мне

"0,6"

Потому что он в Германии и имеет другую культуру.

Какой лучший способ правильно проанализировать оба этих входа? Кто-то предложил использовать CultureInfo.InvariantCulture в качестве аргумента для Convert.ToDouble, но разве это не поможет, если я создаю вышеприведенные строки, а не тогда, когда кто-то другой может отправить мне другие строки?

Правильно ли я считаю, что мне нужно знать исходную культуру и изменить Thread.CurrentThread.CurrentCulture для соответствия, прежде чем пытаться конвертировать?

Ответы [ 4 ]

3 голосов
/ 18 января 2012

Если вы знаете исходную культуру и можете получить экземпляр CultureInfo, представляющий его, вы можете передать его методу Convert.ToDouble или Double.Parse в качестве параметра.Например, если у вас есть это от (известного) немецкого пользователя:

var cultureInfo = CultureInfo.GetCultureInfo("de-DE");
double result = Double.Parse("0,5", cultureInfo);

Если вы не уверены, но имеете ограниченный диапазон исходных культур, то вы можете использовать число Double.TryParseпопытки с различными культурами.Однако, как было указано ниже, «1000» могут иметь совершенно разные значения в зависимости от культуры ...

2 голосов
/ 18 января 2012

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

1 голос
/ 18 января 2012

Это машина или человек, который отправляет это? Если это машина, то есть на другом компьютере есть приложение, которое решает, какие данные отправлять, а не является «слепой» передачей пользовательского ввода, тогда формат для таких вещей должен быть указан, а не зависеть от локали. Как правило, это означает, что вы оба согласны использовать CultureInfo.InvariantCulture или эквивалентную культуру, если другое приложение не является .NET.

Если это человек, и вы знаете его язык, тогда вы можете использовать double.Parse(decString, cultureInfo). Это может потерпеть неудачу, например, если какой-нибудь человек, говорящий по-английски, позаимствует компьютер своего друга, говорящего по-немецки.

Если вы знаете, что не будет никаких группирующих разделителей (например, 123,456.78 или 123'457,78), тогда вы можете использовать double.Parse(decString.Replace(',', '.'), CultureInfo.InvariantCulture), но не можете, если есть группировки, поскольку это означает, что 123,456.78 становится 123.456.78.

0 голосов
/ 18 января 2012

Наилучшая ситуация, когда отправитель и получатель всегда используют одну и ту же Культуру для передачи данных. В вашем текущем случае: даже немецкая машина должна отправить «0,5».

Следующая лучшая вещь в теории - настроить параметры получателя так, чтобы они соответствовали настройкам отправителя. Хотя на практике это сложнее, чем в предыдущем случае: без сотрудничества с отправителем невозможно точно определить культуру. И когда вы можете заставить отправителя сотрудничать, вам лучше заставить его посылать нужную вам культуру. Таким образом, вы практически не видите этого на практике.

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


Так что лучшее, что нужно сделать - это выбрать культуру (обычно InvariantCulture) и настроить отправителя. В конечном итоге вам будет лучше.

...