String.Compare(String, String, StringComparison)方法
这是C#中用来比较两个字符串的较好方法,原因如下:
1. 可以选择是否忽略单词大小写,相比于将单词全转换为大写(toUpperCase())或小写(toLowerCase())后再比较,String.Compare的效率更高。
2. 可以设置是否采用文化敏感(culture-sensitive)的排序规则,其中,(StringComparsion.)CurrentCulture和InvariantCulture是文化敏感的;Ordinal是非文化敏感的,该模式下会比较字符的原始字节码的值。为什么会有上述关于文化敏感的选择呢?微软的官方文档(https://msdn.microsoft.com/en-us/library/ms973919.aspx)里介绍了下述的“The Turkish-I”问题:
For nearly all Latin alphabets, including U.S. English, the character i (\u0069)
is the lowercase version of the character I (\u0049).
This casing rule quickly becomes the default for someone programming in such a culture. However, in Turkish ("tr-TR"),
there exists a capital "i with a dot," character (\u0130),
which is the capital version of i.
Similarly, in Turkish, there is a lowercase "i without a dot," or (\u0131),
which capitalizes to I.
This behavior occurs in the Azeri culture ("az") as
well.
大意是,几乎所有的拉丁字母表,包括美国英语,字符i (\u0069) 是字符I (\u0049) 的小写版本,这个大小写规则也是身处这样的文化中的程序员采用的默认规则。但是,在土耳其语里("tr-TR"),存在大写的“有个点的i”,即 (\u0130),它是i的大写版本;类似,土耳其语里也存在小写的“没有点的i”,即 (\u0131),它大写就是I。这一现象在Azeri文化("az")中也存在。
另外也可以参考下面这个例子(http://*.com/questions/492799/difference-between-invariantculture-and-ordinal-string-comparison):
var s1 = "Strasse";
var s2 = "Straße";
s1.Equals(s2, StringComparison.Ordinal); //false
s1.Equals(s2, StringComparison.InvariantCulture); //true
这个现象叫字符扩充(character expansion),在InvariantCulture模式下,ß会被扩充为ss。
所以呢,一般比较字符串似乎采用String.Compare(s1, s2, StringComparison.CurrentCulture),或再加上IgnoreCase。