Что означает CultureInfo.InvariantCulture? - PullRequest
147 голосов
/ 18 марта 2012

У меня есть строка текста примерно так:

var foo = "FooBar";

Я хочу объявить вторую строку с именем bar и сделать ее равной первому и четвертому символу моего первого foo, поэтому ясделать это так:

var bar = foo[0].ToString() + foo[3].ToString();

Это работает, как и ожидалось, но ReSharper советует мне поставить Culture.InvariantCulture в скобках, так что эта строка заканчивается так:

var bar = foo[0].ToString(CultureInfo.InvariantCulture)
        + foo[3].ToString(CultureInfo.InvariantCulture);

Что это значит и повлияет ли это на работу моей программы?

Ответы [ 5 ]

131 голосов
/ 18 марта 2012

Не все культуры используют один и тот же формат для дат и десятичных / валютных значений.

Это будет иметь значение для вас при преобразовании входных значений (чтение) , которые хранятся в виде строк, в DateTime, float, double или decimal. Также будет иметь значение, если вы попытаетесь отформатировать вышеупомянутые типы данных в строки (запись) для отображения или хранения.

Если вы знаете, к какой конкретной культуре будут относиться ваши даты и десятичные значения / значения валют, вы можете использовать это конкретное свойство CultureInfo (т.е. CultureInfo("en-GB")). Например, если вы ожидаете ввода пользователя.

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

Значением по умолчанию является CultureInfo.InstalledUICulture, поэтому CultureInfo по умолчанию зависит от настроек выполняемой ОС. Вот почему вы всегда должны убедиться, что информация о культуре соответствует вашим намерениям (см. Ответ Мартина для правильного руководства).

125 голосов
/ 20 января 2013

Когда числа, даты и время форматируются в строки или анализируются из строк, для определения того, как это делается, используется культура. Например. в доминирующей культуре en-US у вас есть следующие строковые представления:

  • 1 000 000,00 - один миллион с двузначной дробью
  • 1/29/2013 - дата публикации

В моей культуре (da-DK) значения имеют строковое представление:

  • 1.000.000,00 - один миллион с двузначной дробью
  • 29-01-2013 - дата публикации

В операционной системе Windows пользователь может даже настроить форматирование чисел и даты / времени, а также выбрать другую культуру, отличную от культуры его операционной системы. Используемое форматирование - выбор пользователя, каким он должен быть.

Таким образом, когда вы форматируете значение, которое будет отображаться для пользователя, например, ToString или String.Format или анализируется из строки, используя DateTime.Parse или Decimal.Parse, по умолчанию используется CultureInfo.CurrentCulture. Это позволяет пользователю контролировать форматирование.

Тем не менее, большая часть форматирования и синтаксического анализа строк - это на самом деле не строки, которыми обмениваются приложение и пользователь, а между приложением и некоторым форматом данных (например, файлом XML или CSV). В этом случае вы не хотите использовать CultureInfo.CurrentCulture, потому что, если форматирование и синтаксический анализ выполняются с разными культурами, он может сломаться. В этом случае вы хотите использовать CultureInfo.InvariantCulture (который основан на культуре en-US). Это гарантирует, что значения могут беспрепятственно возвращаться.

Причина, по которой ReSharper предупреждает вас, заключается в том, что некоторые авторы приложений не знают об этом различии, которое может привести к непредвиденным результатам, но они никогда не обнаруживают этого, потому что их CultureInfo.CurrentCulture равен en-US, который ведет себя так же, как CultureInfo.InvariantCulture , Тем не менее, как только приложение используется в другой культуре, где существует вероятность использования одной культуры для форматирования, а другой для анализа, приложение может перестать работать.

Итак, подведем итог:

  • Используйте CultureInfo.CurrentCulture (по умолчанию), если вы форматируете или анализируете пользовательскую строку.
  • Используйте CultureInfo.InvariantCulture, если вы форматируете или анализируете строку, которая должна анализироваться программным обеспечением.
  • Редко используйте определенную национальную культуру, потому что пользователь не может контролировать, как выполняется форматирование и анализ.
23 голосов
/ 22 мая 2014

По данным Microsoft:

Свойство CultureInfo.InvariantCulture не является ни нейтральным, ни специфическая культура. Это третий тип культуры, который культура нечувствительные. Это связано с английским языком, но не со страной или регионом.

(из http://msdn.microsoft.com/en-us/library/4c5zdc6a(vs.71).aspx)

Таким образом, InvariantCulture похож на культуру "en-US", но не совсем то же самое. Если вы напишите:

var d = DateTime.Now;
var s1 = d.ToString(CultureInfo.InvariantCulture);   // "05/21/2014 22:09:28"
var s2 = d.ToString(new CultureInfo("en-US"));       // "5/21/2014 10:09:28 PM"

тогда s1 и s2 будут иметь формат similair, но InvariantCulture добавляет лидирующие нули, а "en-US" использует AM или PM.

Таким образом, InvariantCulture лучше использовать для внутреннего использования, когда, например, вы сохраняете дату в текстовом файле или анализируете данные. И указанное CultureInfo лучше, когда вы предоставляете данные (дата, валюта ...) конечному пользователю.

4 голосов
/ 29 июня 2016

Для таких вещей, как числа (десятичные точки, запятые в количествах), они обычно предпочтительнее в конкретной культуре.

Подходящим способом сделать это было бы установить его на уровне культуры (для немецкого языка) следующим образом:

Thread.CurrentThread.CurrentCulture.NumberFormat = new CultureInfo("de").NumberFormat;
2 голосов
/ 18 марта 2012

JetBrains предлагает разумное объяснение , но если я работаю над сайтом, который, как я знаю, будет только на английском, я просто проигнорирую это предложение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...