Сравнение строк в 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. Это означает, что сравнение строк и сравнение символов не сравнивают точно то же самое (поэтому они могут иметь разные результаты).