Що означає CultureInfo.InvariantCulture?


177

У мене є такий текст, як:

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);

Що це означає, і чи вплине це на те, як працює моя програма?


2
Дивіться цей SO питання: stackoverflow.com/questions/8492449 / ...
msigman

38
Для тих, хто шукає 5-другу відповідь: CultureInfo.InvariantCulture означає "Мені все одно, я не хочу, щоб культура займалася в першу чергу. Тепер дозвольте мені використовувати тупу річ".
Андрій

5
@Andrew Чи можете ви переписати всі документи MS, pls?
Ятрікс

3
@Yatrix Так, звичайно. Я б залюбки! Хто платить?
Андрій

Відповіді:


154

Не всі культури використовують однаковий формат для дат і знаків десяткової / валюти.

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

Якщо ви знаєте, яка конкретна культура ваших дат і значень десяткової / валюти буде достроково, ви можете скористатися цією CultureInfoвластивістю (тобто CultureInfo("en-GB")). Наприклад, якщо ви очікуєте введення користувачем.

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

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


3
"en-US", хоча, я думаю, це насправді може залежати від ваших налаштувань системи.
Tracker1

44
Значення за замовчуванням не є en-US. Це місцева культура. І InvariantCultureвикористовується , коли ви хочете культури нейтрального форматування , що це НЕ залежить від локальної системи. Наприклад, при роботі з текстовими форматами файлів.
CodesInChaos

23
Щоб додати до коментаря @CodesInChaos: Твердження про те, що значенням за замовчуванням є CultureInfo ("en-US") , просто помилкове. Крім того, вислів властивість CultureInfo.InvariantCulture використовується тоді, коли ви не впевнені заздалегідь, у якому форматі культури будуть розміщуватися ваші дати та значення десяткової / валюти . Використання поточної, інваріантної чи певної культури - це щось, що повинно бути свідомим рішенням, і якщо ви помилитесь, ви можете відчужувати своїх користувачів, які не є США. Не варто використовувати інваріантну культуру, якщо ви "не впевнені". Ви повинні бути впевнені достроково.
Мартін Ліверсайз

3
-1 через проблеми, згадані в інших коментарях. Відповідь Мартіна є більш корисною, оскільки вона говорить вам, коли використовувати та не використовувати кожну культуру.
Ед Грівз

"якщо ви працюєте виключно в американській англійській мові, то вам не потрібно турбуватися про це.": Неправильно, можливо, ви працюєте виключно американською англійською, але програмне забезпечення може працювати на "en-GB" або "de -DE "сервер, то він змінить значення, плюс він може зайняти культуру клієнта (якщо ви так сказати у файлі web.config), і це може бути не" en-US "...
Стефан Штайгер

151

Коли числа, дати та час відформатовані у рядки або проаналізовані з рядків, використовується культура, щоб визначити, як це робиться. Наприклад, у домінуючій 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.CurrentCultureIS , en-USякий має таку ж поведінку , як CultureInfo.InvariantCulture. Однак, як тільки програма використовується в іншій культурі, де є можливість використання однієї культури для форматування, а іншої для розбору програми, може зламатися.

Отже, підсумовуючи це:

  • Використовуйте CultureInfo.CurrentCulture(за замовчуванням), якщо ви форматуєте або аналізуєте рядок користувача.
  • Використовуйте, CultureInfo.InvariantCultureякщо ви форматуєте чи розбираєте рядок, який повинен бути синтаксичний за допомогою програмного забезпечення.
  • Рідко використовуйте певну національну культуру, оскільки користувач не може контролювати, як здійснюється форматування та аналіз.

1
Що стосується останнього пункту, "рідко використовувати конкретну національну культуру ...", чи форматування валюти буде винятком? Наприклад, якщо у мене є Decimalзмінна, яка містить певне значення в доларах США, чи хочу я зробити виняток і використовувати en-USяк культуру під час її відображення, щоб переконатися, що я не отримаю результат, схожий на число в євро? Я спробував CultureInfo.InvariantCulture , але отримав це за валютний маркер ¤, тому не впевнений, що це правильний шлях.
Джефф Б

1
@JeffBridgman: Моя порада - це лише загальна порада і може не стосуватися конкретного випадку. Однак я думаю, що спосіб відображення десяткової крапки (кома або крапка) повинен бути чимось, що користувач контролює (наприклад, використовує CultureInfo.CurrentCulture). Якщо вам, крім того, щоб відобразити номер, потрібна валюта, можливо, ви повинні зробити це послідовно, тобто не використовувати a CultureInfoі замість цього використовувати трибуквенний код валюти, як USD 1,234.56. Тоді ви не стикаєтесь із проблемами відображення валюти в культурі.
Мартін Ліверсайз

26

За даними 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 краще для внутрішнього використання, коли ви, наприклад, зберігаєте дату в текстовому файлі або аналізує дані. А вказана культураInfo краще, коли ви представляєте кінцевому користувачеві дані (дату, валюту ...).


3
Я запустив ваш приклад код для підтвердження: InvariantCulture використовує американський MM / dd / yyyy, а не слідує формату ISO 8601 рік-перший. Незважаючи на те, що він призначений для переносного зберігання та механічної обробки, а не для споживання людиною. Як заплутано
Макс Барраклу

4

Для таких речей, як числа (десяткових знаків, коми в кількостях), вони зазвичай віддають перевагу певній культурі.

Відповідний спосіб зробити це було б встановити це на рівні культури (для німецької мови), як це:

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

4

JetBrains пропонують розумне пояснення ,

"Спеціальне перетворення структур даних у текст значною мірою залежить від поточної культури і може призвести до ненавмисних результатів, коли код виконується на машині, локаль якої відрізняється від оригінального розробника. Щоб запобігти двозначності, ReSharper попереджає вас про будь-які випадки в коді, де може виникнути така проблема. "

але якщо я працюю над сайтом, який я знаю, буде лише англійською мовою, я просто ігнорую пропозицію.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.