Что обычно лучше всего использовать - StringComparison.OrdinalIgnoreCase или StringComparison.InvariantCultureIgnoreCase?

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

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

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

Ответ 1

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

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

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

Ответ 2

Все зависит от

Сравнение строк unicode затруднено:

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

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


Если вы пытаетесь сравнить 2 строки Unicode в режиме без учета регистра и хотите, чтобы он работал ВЕСЬ, у вас есть невозможная проблема.

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

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

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


Тем не менее иногда нам нужна "общая цель", не чувствительная к регистру, сравнение.

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

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

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

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

который вы выбираете, зависит от приложения, которое вы строите.

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

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

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

Ответ 4

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

Ответ 5

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

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