Почему OrdinalIgnoreCase и InvariantCultureIgnoreCase возвращают разные результаты?

Я думал, что StringComparison.OrdinalIgnoreCase и StringComparison.InvariantCultureIgnoreCase выполняют ту же работу, когда речь идет о строках только для английского. Однако это не так в следующем коде, над которым я работаю:

// Returns 0
string.Compare("877495169FA05B9D8639A0EBC42022338F7D2324","‎877495169fa05b9d8639a0ebc42022338f7d2324", StringComparison.InvariantCultureIgnoreCase)

// Returns -1
string.Compare("877495169FA05B9D8639A0EBC42022338F7D2324","‎877495169fa05b9d8639a0ebc42022338f7d2324", StringComparison.OrdinalIgnoreCase)

Есть ли какая-то особая причина?

Ответ 1

"‎877495169fa05b9d8639a0ebc42022338f7d2324"

Звучит как трюк. Там есть дополнительный символ в начале этой строки, перед первой цифрой 8. Он не отображается в браузере. Это U + 200E, "Слева от правого знака". По порядковому сравнению этот символ, инвариантное сравнение игнорирует его. Вы можете увидеть это сами, используя ToCharArray() в строке.

Удалите эту строку и вставьте ее вместо этого, я удалил из нее U + 200E:

"877495169fa05b9d8639a0ebc42022338f7d2324"

И метод Compare() теперь возвращает 0, как и должно. Следите за тем текстовым редактором или IME, которые вы используете прямо сейчас. Разве Unicode не весело?