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

StackOverflow https://stackoverflow.com/questions/72696

  •  09-06-2019
  •  | 
  •  

Вопрос

У меня есть какой-то код, подобный этому:

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

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

Это было полезно?

Решение

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

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

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

Другие советы

Все зависит от обстоятельств

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

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

видишь: http://en.wikipedia.org/wiki/Unicode_equivalence


Если вы пытаетесь сравнить 2 строки в юникоде без учета регистра и хотите, чтобы это сработало ПОВСЮДУ, - у вас неразрешимая проблема.

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

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

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


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

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

Для достижения этой цели у нас есть 3 варианта:

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

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

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

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

У Microsoft есть свои набор рекомендаций с четкими руководящими принципами.Однако действительно важно понять понятие эквивалентности Unicode, прежде чем приступать к решению этих проблем.

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

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

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

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

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

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

Смотрите следующую ссылку:

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top