Что обычно лучше всего использовать - StringComparison.OrdinalIgnoreCase или StringComparison.InvariantCultureIgnoreCase? - PullRequest
138 голосов
/ 16 сентября 2008

У меня есть такой код:

If key.Equals("search", StringComparison.OrdinalIgnoreCase) Then
    DoSomething()
End If

Мне нет дела до дела. Должен ли я использовать OrdinalIgnoreCase, InvariantCultureIgnoreCase или CurrentCultureIgnoreCase?

Ответы [ 6 ]

151 голосов
/ 16 сентября 2008

В новых .Net Docs теперь есть таблица, которая поможет вам решить, что лучше всего использовать в вашей ситуации.

Из MSDN " Новые рекомендации по использованию строк в Microsoft .NET 2.0 "

Резюме. Владельцам кода, ранее использовавшим InvariantCulture для сравнения, сортировки и сортировки строк, следует строго рассмотреть возможность использования нового набора перегрузок String в Microsoft .NET 2.0. В частности, данные, предназначенные для не зависящих от культуры и не относящихся к языку , должны начинать указывать перегрузки, используя элементы StringComparison.Ordinal или StringComparison.OrdinalIgnoreCase нового перечисления StringComparison. Они обеспечивают побайтовое сравнение, подобное strcmp, которое не только устраняет ошибки в лингвистической интерпретации по существу символьных строк, но и обеспечивает лучшую производительность.

56 голосов
/ 20 июня 2011

Все зависит

Сравнивать строки в юникоде сложно:

Реализация строки Unicode поиск и сравнение в тексте программное обеспечение для обработки должно принимать во учитывать наличие эквивалента кодовые точки. При отсутствии этого особенность, пользователи ищут конкретная последовательность кодов будет быть не в состоянии найти другое визуально неразличимые глифы, которые имеют разные, но канонически эквивалентные, представление кодовой точки.

см .: http://en.wikipedia.org/wiki/Unicode_equivalence


Если вы пытаетесь сравнить 2 строки юникода без учета регистра и хотите, чтобы он работал ВЕЗДЕ , у вас возникла проблема.

Классическим примером является Turkish i , который в верхнем регистре становится İ (обратите внимание на точку)

По умолчанию .Net Framework обычно использует CurrentCulture для функций, связанных со строками, с очень важным исключением .Equals, которое использует порядковое (побайтное) сравнение.

Это приводит к тому, что различные строковые функции ведут себя по-разному в зависимости от культуры компьютера.


Тем не менее, иногда мы хотим «общего назначения», без учета регистра, сравнения.

Например, вы можете захотеть, чтобы сравнение строк велось одинаково, независимо от того, на каком компьютере установлено приложение.

Для этого у нас есть 3 варианта:

  1. Установите явную культуру и выполните сравнение без учета регистра, используя правила эквивалентности Юникода.
  2. Установите для культуры значение Инвариантная культура и выполняйте сравнение без учета регистра, используя правила эквивалентности Юникода.
  3. Используйте OrdinalIgnoreCase , который будет вводить строку в верхнем регистре с использованием InvariantCulture, а затем выполнять побайтовое сравнение.

Правила эквивалентности Юникода сложны, что означает, что использование метода 1) или 2) обходится дороже, чем OrdinalIgnoreCase. Тот факт, что OrdinalIgnoreCase не выполняет какой-либо специальной нормализации Юникода, означает, что некоторые строки, которые одинаково отображаются на экране компьютера, не будут считаться идентичными. Например: "\u0061\u030a" и "\u00e5" оба рендеринга. Однако в порядковом сравнении будет считаться другим.

То, что вы выберете, во многом зависит от приложения, которое вы создаете.

  • Если бы я писал бизнес-приложение, которое использовалось только турецкими пользователями, я бы обязательно использовал метод 1.
  • Если бы мне просто потребовалось простое «ложное» сравнение без учета регистра, например, имя столбца в БД, которое обычно является английским, я бы, вероятно, использовал метод 3.

У Microsoft есть набор рекомендаций с четкими рекомендациями. Тем не менее, очень важно понять понятие эквивалентности Юникода, прежде чем подходить к этим проблемам.

Кроме того, имейте в виду, что OrdinalIgnoreCase - это очень особенный вид зверя, который выбирает и выбирает немного порядкового сравнения с некоторыми смешанными в лексикографических аспектах. Это может сбивать с толку.

8 голосов
/ 16 сентября 2008

MSDN дает довольно четкие рекомендации по этому поводу: http://msdn.microsoft.com/en-us/library/ms973919.aspx

3 голосов
/ 16 сентября 2008

Я думаю, это зависит от вашей ситуации. Поскольку порядковые сравнения на самом деле смотрят на числовые значения Unicode символов, они не будут лучшим выбором при сортировке по алфавиту. Однако для сравнения строк порядковый номер будет чуть быстрее.

1 голос
/ 16 сентября 2008

Это зависит от того, что вы хотите, хотя я бы избегал инвариантной культуры, если вы не очень уверены, что вы никогда не захотите локализовать код для других языков. Вместо этого используйте CurrentCulture.

Кроме того, OrdinalIgnoreCase должен учитывать числа, которые могут совпадать или не совпадать с вашими.

0 голосов
/ 18 июля 2012

Очень простой ответ: если вы не используете турецкий язык, вам не нужно использовать InvariantCulture.

См. Следующую ссылку:

В C # в чем разница между ToUpper () и ToUpperInvariant ()?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...