Что означает 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 предлагает разумное объяснение, но если я работаю над сайтом, который, как я знаю, будет только на английском языке, я просто игнорирую это предложение.