Сравнение строк в 1 длину дает другой результат, чем сравнение символов... почему?
Я новичок в С#, и я нашел что-то неожиданное в сравнении строк, которое я действительно не понимаю.
Может ли кто-нибудь объяснить мне, почему сравнение между символами дало противоположный результат как сравнение строк длины символа в следующем коде?
Я ожидал, что "9" < "="
будет true
(поскольку код Юникода из 9 (57) меньше, чем код юникода '=' (61)), но он неверен... Какова логика сравнения строки позади и почему это отличается от сравнения персонажей?
Код:
bool resChComp = '9' < '=';
bool resStrComp = String.Compare("9", "=") < 0;
Console.WriteLine($"\n'9' < '=' : {resChComp}, \"9\" < \"=\" : { resStrComp }");
Выход:
'9' < '=' : True, "9" < "=" : False
Ответы
Ответ 1
Сравнение строк по умолчанию делает "сортировку слов". Из документации,
В.NET Framework используются три разных способа сортировки: сортировка слов, сортировка строк и сортировка по порядку. Сортировка слов выполняет культурное сравнение строк. Определенные неасфальтированные символы могут иметь специальные веса, назначенные им. Например, дефис ("-") может иметь очень небольшой вес, назначенный ему, чтобы "курятник" и "кооператив" отображались рядом друг с другом в отсортированном списке. Строковая сортировка похожа на сортировку слов, за исключением того, что особых случаев нет. Поэтому все неальфанумерные символы поступают перед всеми буквенно-цифровыми символами. Ordinal sort сравнивает строки, основанные на значениях Unicode для каждого элемента строки.
Сравнение, которое вы ожидаете, является порядковым сравнением, которое вы можете получить, используя StringComparison.Ordinal
в перегрузке String.Compare
, например:
bool resStrComp = String.Compare("9", "=", StringComparison.Ordinal) < 0;
Это будет сравнивать строки, используя их значения в unicode, так же, как и сравнение символа с другим символом.
Ответ 2
Это связано с тем, что String.Compare по умолчанию использует сортировки слов, а не числовые значения для символов. Просто случается так, что для используемой культуры 9
приходит до =
в порядке сортировки.
Если вы укажете правила сортировки ординарных (двоичных), упомянутые здесь, они будут работать так, как вы ожидаете.
bool resStrComp = String.Compare("9", "=", StringComparison.Ordinal) < 0;
Ответ 3
В случае сравнения символов символы будут переданы в int
соответствующем значению ASCII. 9
имеет значение ASCII 57, а =
имеет значение 61. Это означает, что сравнение строк и сравнение символов не сравнивают точно то же самое (поэтому они могут иметь разные результаты).