字符串比较:InvariantCultureIgnoreCase与OrdinalIgnoreCase有什么区别?

227

哪种代码更好:

int index = fileName.LastIndexOf(".", StringComparison.InvariantCultureIgnoreCase);

或者

int index = fileName.LastIndexOf(".", StringComparison.OrdinalIgnoreCase);

12
那取决于你想要实现什么目标...... - Mitch Wheat
4
将C#问题标记为VB.NET问题的重复问题...至少有点有趣。相信在这种情况下两者都应该共享.Net标签。 - Lanorkin
1
@Lanorkin:在VB.NET和C#中,这两个枚举值之间的区别是相同的,而且对于这两个问题的任何答案都不特定于VB.NET或C#。这两个问题显然是重复的,通过将它们关联起来,可以更容易地找到有关这些枚举值的相关信息。 - Martin Liversage
1
@MartinLiversage 没错,这就是为什么我用“有趣”的词语。 - Lanorkin
我不认为这是一个重复的问题,因为这个问题是关于文件名解析的,而另一个问题似乎是关于用户输入的。文件名解析有不同的要求。我希望标题以“文件名字符串比较:...”开头,那么这个问题就会更清晰明了。 - Ron
4个回答

311

没有哪种代码总是更好。它们执行不同的任务,因此在不同的场景下表现出色。

InvariantCultureIgnoreCase 使用基于英语的比较规则,并且没有任何区域差异。这适用于进行中性比较,同时仍考虑某些语言方面的因素。

OrdinalIgnoreCase 比较字符代码而不考虑文化方面的因素。这适用于精确比较,例如登录名,但不适合对具有非常规字符(例如éö)的字符串进行排序。由于在比较之前没有应用额外的规则,因此这也更快速。


9
当遇到 ä 时,InvariantCultureIgnoreCase 如何行动?与 OrdinalIgnoreCase 相比呢? - Royi Namir
25
是的,在进行比较时,将忽略大小写。OrdinalIgnoreCase 进行大小写转换,但是在比较字符代码时进行比较,所以 àÀ 相等,但 AÀ 不同。 - Guffa
9
根据你给我的第一条评论:为什么这段代码 string s1 = "hello";string s2 = "héllo"; s1.Equals(s2, StringComparison.InvariantCulture) 返回 False?你说a和à被视为相同的... - Royi Namir
11
是的,你说得对,这些字符并没有被视为完全相等,但是当你对字符串进行排序时,é 会紧随 e 而不是在 z 之后。 - Guffa
14
是的,对于该字符来说是这样的,其他字符可能被评估为相等,或者一个字符可能等于另外两个字符。字符串 "lasst" 和 "laßt" 实际上是相等的。 - Guffa
显示剩余10条评论

64

FXCop通常偏爱使用OrdinalIgnoreCase。但您的要求可能会有所不同。

对于英语来说,差别很小。但当你涉及到拥有不同书写语言结构的语言时,这就成为一个问题了。我没有足够的经验来给你更多建议。

OrdinalIgnoreCase

OrdinalIgnoreCase属性返回的StringComparer将字符串中的字符视为使用不变文化的约定将其转换为大写字母,然后执行独立于语言的简单字节比较。 在比较由程序生成的字符串或比较不区分大小写的资源(如路径和文件名)时最合适。 http://msdn.microsoft.com/en-us/library/system.stringcomparer.ordinalignorecase.aspx

InvariantCultureIgnoreCase

InvariantCultureIgnoreCase属性返回的StringComparer以在语言上相关的方式比较字符串,忽略大小写,但它不适合在任何特定文化中显示。 其主要应用程序是按照将在各种文化中相同的方式排序字符串。 http://msdn.microsoft.com/en-us/library/system.stringcomparer.invariantcultureignorecase.aspx

不变文化是由InvariantCulture属性返回的CultureInfo对象。

InvariantCultureIgnoreCase属性实际上返回一个从StringComparer类派生的匿名类的实例。


55
如果您真的只想匹配句点,那么StringComparison.Ordinal会是最快的选择,因为没有大小写区分。
"Ordinal"不使用文化和/或大小写规则,在像.这样的符号上也不适用。

18
你似乎正在进行文件名比较,因此我建议使用OrdinalIgnoreCase,这个选项最接近NTFS的操作方式(虽然不完全一样,但比InvariantCultureIgnoreCase更接近)。

9
你有NTFS相关资料的参考文献吗? - Basic

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