У мене такий код:
If key.Equals("search", StringComparison.OrdinalIgnoreCase) Then
DoSomething()
End If
Мене не хвилює справа. Повинен чи я використовувати OrdinalIgnoreCase
, InvariantCultureIgnoreCase
або CurrentCultureIgnoreCase
?
У мене такий код:
If key.Equals("search", StringComparison.OrdinalIgnoreCase) Then
DoSomething()
End If
Мене не хвилює справа. Повинен чи я використовувати OrdinalIgnoreCase
, InvariantCultureIgnoreCase
або CurrentCultureIgnoreCase
?
Відповіді:
З " Нових рекомендацій щодо використання рядків у Microsoft .NET 2.0 " від MSDN
Резюме: Власники коду, які раніше використовували
InvariantCulture
для порівняння рядків, корпусів та сортування, повинні наполегливо розглянути можливість використання нового наборуString
перевантажень у Microsoft .NET 2.0. В Зокрема, дані , які розроблені , щоб бути культурно-агностиком і лінгвістично значення повинні починатися з зазначенням перевантажень , використовуючи абоStringComparison.Ordinal
абоStringComparison.OrdinalIgnoreCase
член новогоStringComparison
перерахування. Вони забезпечують порівняння байт-байт, подібне до того,strcmp
що не лише дозволяє уникнути помилок у мовній інтерпретації по суті символічних рядків, але забезпечує кращу ефективність.
"Straße"
та "STRASSE"
. При використанні OrdinalIgnoreCase
на Equals
віддачу false
, а InvariantCultureIgnoreCase
говорить , що вони рівні.
Порівнювати рядки Unicode важко:
Реалізація пошукових рядків Unicode та порівнянь у програмі для обробки тексту повинна враховувати наявність еквівалентних кодів. За відсутності цієї функції користувачі, які шукають певну послідовність кодових точок, не зможуть знайти інших візуально нерозрізних гліфів, які мають інше, але канонічно еквівалентне представлення кодової точки.
дивіться: http://en.wikipedia.org/wiki/Unicode_equivalence
Якщо ви намагаєтеся порівняти 2 рядки Unicode у випадку нечутливого до справи, і хочете, щоб він працював КОЖНО , у вас є неможлива проблема.
Класичний приклад - турецький i , який у верхньому регістрі стає İ (зауважте крапку)
За замовчуванням .Net Framework зазвичай використовує CurrentCulture для функцій, пов’язаних із рядками, за дуже важливим винятком.Equals
що використовує порядкове (байт за байтом) порівняння.
Це призводить, за задумом, до того, що різні струнні функції поводяться по-різному залежно від культури комп'ютера.
Тим не менш, іноді ми хочемо "загального призначення", нечутливого до випадку, порівняння.
Наприклад, ви можете хотіти, щоб ваше порівняння рядків поводилося однаково, незалежно від того, на якому комп'ютері встановлено вашу програму.
Для цього у нас є 3 варіанти:
Правила еквівалентності Unicode є складними, це означає, що використання методу 1) або 2) дорожче, ніж OrdinalIgnoreCase
. Те, що OrdinalIgnoreCase
не виконує жодної спеціальної нормалізації унікоду, означає, що деякі рядки, які відображаються однаково на екрані комп'ютера, не вважатимуться ідентичними. Наприклад: "\u0061\u030a"
і "\u00e5"
обидва представляють å. Однак у порядковому порівнянні буде розглянуто інше.
Якого ви обираєте сильно, залежить від програми, яку ви будуєте.
Microsoft має набір рекомендацій із чіткими вказівками. Однак, дійсно важливо зрозуміти поняття еквівалентності унікоду до наближення цих проблем.
Крім того, майте на увазі, що OrdinalIgnoreCase - це особливий вид звіра, який підбирає і вибирає трохи порядкового порівняння з деякими змішаними в лексикографічному аспектах. Це може заплутати.
Це залежить від того, що ви хочете, хоч я б ухилявся від інваріантської культури, якщо ви не дуже впевнені , що ви ніколи не хочете , щоб локалізувати код для інших мов. Замість цього використовуйте CurrentCulture.
Також OrdinalIgnoreCase має поважати цифри, які можуть бути або не бути такими, які ви хочете.
Дуже проста відповідь: якщо ви не використовуєте турецьку мову, вам не потрібно використовувати InvariantCulture.
Дивіться наступне посилання: