Что означает 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);

Что это значит, и повлияет ли это на мою программу?

Ответ 1

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

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

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

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

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

Ответ 2

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

Ответ 3

Согласно 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 лучше для внутреннего использования, когда вы e.g сохраняете дату в текстовом файле или анализируете данные. И указанная CultureInfo лучше, когда вы представляете конечным пользователям данные (дата, валюта...).

Ответ 4

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

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

Thread.CurrentThread.CurrentCulture.NumberFormat = new CultureInfo("de").NumberFormat;

Ответ 5

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