Почему строки в .net по умолчанию чувствительны к регистру?

В большинстве случаев я хочу делать сравнения строк, я хочу, чтобы они были нечувствительны к регистру.

Итак, почему строки в .net по умолчанию чувствительны к регистру?

EDIT 1: Чтобы было ясно, я думаю, что приведенное ниже должно возвращать true по умолчанию. Или, по крайней мере, позвольте мне иметь флаг времени компиляции, который делает это так.

"John Smith" == "JOHN SMITH" 

РЕДАКТИРОВАТЬ 2: я могу привести множество других примеров того, что должно быть нечувствительным к регистру.

Примеры вещей, которые должны быть нечувствительны к регистру

  • Имена пользователей
  • URL-адреса
  • Расширения файлов/Имена файлов/Имена каталогов/Пути
  • Имена машин/серверов
  • Штат/страна/местоположение и т. д.
  • Имя / Фамилия / Инициалы
  • Руководства
  • Названия месяца/дня

Примеры вещей, которые должны быть чувствительны к регистру

  • Пароли

person Simon    schedule 13.12.2010    source источник
comment
@Брайан. Вы правы, это мой опыт. хотя сравнивать с деньгами не совсем точно   -  person Simon    schedule 14.12.2010
comment
+1 закрыть. Похоже, вам интереснее выразить свое несогласие с решением, чем начать честное расследование.   -  person Bryan Watts    schedule 14.12.2010
comment
@ Брайан: не совсем так. Я излагаю свое обоснование вопроса. Что я надеюсь получить из этого, так это некую окончательную причину того, почему было принято противоположное решение. Возможно, это должна быть вики сообщества??   -  person Simon    schedule 14.12.2010
comment
Саймон: Подумайте об этом с другой стороны: сравнение с учетом регистра уже достаточно сложно и каждая функция начинается с -100 баллов — должны быть очень веские причины, чтобы добавить дополнительную сложность, сделав ее по умолчанию нечувствительной к регистру. Кроме того, таким образом вы добавляете неожиданное поведение, например, ß сравнивается в равной степени с ss, что не обязательно всегда предполагается.   -  person Joey    schedule 14.12.2010
comment
URI не чувствительны к регистру, только часть домена и схемы. GUID, вероятно, следует сравнивать как GUID, а не как строки, что также делает этот вопрос спорным.   -  person Joey    schedule 14.12.2010
comment
@Simon: утверждение, что "John Smith" == "JOHN SMITH" должно возвращать true, указывает на ваше несогласие. Ваша готовность использовать переплетение IL, чтобы ниспровергнуть языковое решение, свидетельствует о пренебрежении. Эти свойства вопроса, как правило, приводят к субъективным и аргументированным ответам. Я понимаю, вы спрашиваете о том, почему было принято решение, но ваш подход перегружен вашим мнением.   -  person Bryan Watts    schedule 14.12.2010
comment
Не согласен с вами в сравнении имени пользователя, что чувствительность к регистру добавляет безопасности в ситуацию...   -  person tekiegreg    schedule 14.12.2010
comment
@tekiegreg: это больше раздражает пользователей, чем безопасность. По крайней мере, в любой реальной системе, которую я видел до сих пор. Он прав в том, что для пользователей почти ничего не должно быть чувствительным к регистру. Но для языка программирования общего назначения я думаю, что это неправильный путь.   -  person Joey    schedule 14.12.2010
comment
Я бы никогда не стал утверждать, что они должны быть нечувствительны к регистру по умолчанию. Тем не менее, я действительно думаю, что было бы лучше предоставить лучший способ делать сравнения без учета регистра, чем использование вспомогательных методов, которые заставляют ваш код исчезать с экрана или занимать несколько строк. Другой тип, представляющий тип строки, нечувствительный к регистру, был бы великолепен, или даже просто какой-то синтаксический сахар... возможно, перегрузка или создание какого-то нового оператора для этой цели.   -  person BVernon    schedule 21.08.2015
comment
Конечно... в списке замечательных функций я уверен, что это не самое первое место в списке, поэтому я понимаю, почему они этого не сделали.   -  person BVernon    schedule 21.08.2015


Ответы (8)


Извините за банальный ответ, но так оно и есть :)

На базовом уровне строки представлены в виде списка символов, где «а» отличается от «А», поэтому это, вероятно, самое простое представление \ соглашение в целом. В вашем случае, вероятно, будет справедливо сказать, что большинство сравнений нечувствительны к регистру, но я думаю, что другая сторона аргумента верна, по крайней мере, в такой же степени, и соглашение было принято.

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

person cristobalito    schedule 13.12.2010
comment
Так ваш ответ они не думали об этом или это из соображений производительности? - person Simon; 14.12.2010
comment
@cristobalito Мне не нужны вспомогательные методы. Я хочу, чтобы John Smith == JOHN SMITH возвращал true. - person Simon; 14.12.2010
comment
Я бы предположил, что это в основном историческая проблема - так всегда делалось и чего люди, вероятно, ожидают. Я был бы очень удивлен, если бы abc == ABC возвращал true из коробки. Кроме того, как вы намекаете, это также более затратно в вычислительном отношении и, кроме того, я думаю, вы, вероятно, начнете сталкиваться с дополнительными проблемами, когда начнете рассматривать юникод. - person cristobalito; 14.12.2010
comment
@simon Но Джон Смит не равен ДЖОНУ СМИТУ. Ну не к компу - person PostMan; 14.12.2010
comment
@Simon - для такой функции, я думаю, вам нужно сменить язык. Хотя я не могу придумать ничего из того, что приходит мне в голову (html?) - person cristobalito; 14.12.2010
comment
@cristobalito снова сменить язык... возможно. Я думаю об использовании IL Weaving, как в этом проекте code.google.com/p/virtuosity. - person Simon; 14.12.2010
comment
@Simon: Ты тот же Саймон, что и Саймон в этом проекте? - person cristobalito; 14.12.2010

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

StringComparison.OrdinalIgnoreCase
StringComparison.InvariantCultureIgnoreCase
StringComparison.CurrentCultureIgnoreCase

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

person usr    schedule 26.07.2013

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

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

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

person T.Rob    schedule 13.12.2010

Сравнение строк в .Net чувствительно к регистру, поскольку строки (и отдельные символы) по своей природе чувствительны к регистру.

Символ «a» хранится внутри с другим значением ASCII или Unicode как «A». Говорить, что «а» — это то же самое, что «А», «неправильно».

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

Мои два цента: сравнение с учетом регистра используется по умолчанию, потому что оно правильное.

person Bob Black    schedule 14.12.2010

В VB.NET можно установить «параметр сравнения» с текстом, чтобы он работал без учета регистра, но я настоятельно не рекомендую это делать. Мне больше всего нравится использовать метод string.toLower(), когда мне нужно нечувствительно сравнить и прочитать версию текста в нижнем регистре.

Почему? Потому что, как еще вы могли бы сравнить, когда чувствительность к регистру имеет значение, как это было бы в некоторых приложениях?

person tekiegreg    schedule 13.12.2010
comment
Почему бы не использовать встроенный string.Compare(string, string, bool) (msdn.microsoft.com/en-us/library/zkcaxw5y.aspx) - person cristobalito; 14.12.2010
comment
как еще вы сравните, когда чувствительность к регистру имеет значение, как в некоторых приложениях, использующих string.Equals(a, b, StringComparison.CurrentCulture); вместо string.Equals(a, b, StringComparison.CurrentCultureIgnoreCase); - person Simon; 14.12.2010
comment
a.Equals(b, StringComparison.OrdinalIgnoreCase) должен быть лучше, чем выполнение ToLower для строки. - person Pauli Østerø; 14.12.2010
comment
Хорошие моменты, не подумал о них. Но я работал над гипотетическим сценарием с языком, нечувствительным только к регистру, давайте просто предположим на мгновение, что не было способа заявить или указать чувствительность к регистру, что теперь? - person tekiegreg; 14.12.2010

Вы не можете изменить поведение существующих классов. System.String, который определен в mscorelib/system.core, переопределяет == и определяет равенство с учетом регистра.

Все, что вы можете сделать, это добавить метод расширения к строке и реализовать нечувствительный к регистру:

public static class StringEqualityExtension
{
    public static bool StringEquals(this string value, string other)
    {
       return value.ToLower()==other.ToLower();
    } 
}

// usage
string myString = "Some112";
string other = "sOME112";

bool equal = myString.StringEquals(myString);
person Aliostad    schedule 14.12.2010

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

Сопоставление примечаний без учета регистра тривиально просто. На самом деле метод equals для строки имеет перегруженную версию специально для указания способа сравнения.

person Tim Jarvis    schedule 14.12.2010

Я знаю, что это некропостинг, но

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

Согласно этой странице MSDN, вам просто нужно добавить 1 строку кода в ваш файл:

Option Compare Text

Если вы добавите приведенную выше строку в начало вашего ядра, вы скажете CLR переключиться с сравнения по умолчанию (Option Compare Binary) на сравнение без учета регистра.

Я не знаю, может ли это работать на С#.

person beppe9000    schedule 23.06.2015