为什么OrdinalIgnoreCase和InvariantCultureIgnoreCase返回不同的结果?

11

我曾认为StringComparison.OrdinalIgnoreCaseStringComparison.InvariantCultureIgnoreCase在处理仅包含英语的字符串时可以完成相同的工作。然而,在我正在处理的以下代码中,情况并非如此:

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

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

有特别的原因吗?


2
可能是InvariantCulture和Ordinal字符串比较之间的区别的重复问题。 - Daniel A. White
3
@DanielA.White 这个问题绝对不是那个问题的重复。我认为你没有读这个问题。 - Daniel A.A. Pelsmaeker
1个回答

26
"‎877495169fa05b9d8639a0ebc42022338f7d2324"

听起来像是一个诡计问题。在这个字符串的开头,在第一个数字8之前有一个额外的字符。它在浏览器中是不可见的。它是U+200E,“从左到右标记”。序数比较会看到该字符,而不变比较会忽略它。你可以通过在字符串上使用ToCharArray()函数来自己查看它。

删除那个字符串,然后将这个字符串粘贴进去,我已经将其中的U+200E删除了:

"877495169fa05b9d8639a0ebc42022338f7d2324"

现在,Compare() 方法返回了应该返回的0。请注意您现在使用的文本编辑器或IME。Unicode很有趣,不是吗?


发现得好。在我的Notepad++中,它显示为一个问号:“?877495169fa05b9d8639a0ebc42022338f7d2324”。 - Daniel A.A. Pelsmaeker
3
谢谢!这并不是一个诡计问题,我实际上从certmgr.msc复制了一个证书的指纹字符串到我的程序中,但是与之比较失败了。我不知道它可能包含看不见的字符。结果发现,即使在Visual Studio中也无法显示这些字符。这很有趣! - Todd Li
1
好的,这样更有意义。为了记录:这是哪个语言版本的Windows生成的? - Hans Passant
1
Windows 8 Enterprise en-US。 - Todd Li

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接