Что означает CultureInfo.InvariantCulture?

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

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 ответов

Решение

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

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

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

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

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

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

  • 1 000 000,00 - один миллион с двузначной дробью
  • 29.01.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 если вы форматируете или анализируете строку, которая должна быть проанализирована программным обеспечением.
  • Редко используйте определенную национальную культуру, потому что пользователь не может контролировать, как выполняется форматирование и анализ.

По словам 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 лучше, когда вы предоставляете данные (дата, валюта...) конечному пользователю.

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

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

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

Thread.CurrentThread.CurrentCulture.NumberFormat = new CultureInfo("de").NumberFormat;
Другие вопросы по тегам