ASCII比较和字符串比较之间的区别
我正在使用C#。 当我比较两个char值时,它给我发送正确的输出,比如,
'-'.CompareTo('!') //Its sending me positive value 12
意思是‘ – ‘>’!’ 是真的
但是当我比较两个相同值的字符串时,它给我发送了不同的结果
"-".CompareTo("!") //Its sending me negative value -1
意思是“ – ”>“!” 是假的
任何人都可以解释我为什么这样做? 这两种情况都不应该是“真的”吗?
String的Compare方法是特定于文化的。 这就是为什么你得到不同的结果。 使用string.CompareOrdinal
,这是逐字节比较。
var v = '-'.CompareTo('!');//12 var s = string.CompareOrdinal("-", "!");//12
在.NET Framework中使用字符串的最佳实践
这个比较'-'.CompareTo('!')
将执行序数比较 。 它将比较数字UTF-16编码值( 45
和33
)。
字符串比较"-".CompareTo("!")
不同,它将执行文化感知比较 。 这意味着,无论数值如何,字符都将根据当前文化的排序规则进行排序 。
您可以尝试使用字符串的序数比较:
String.CompareOrdinal("-", "!")
这将对字符串执行序数比较,然后您将得到相同的结果( 12
)。
你不能对Char
执行(真正的)文化感知比较(如果你需要它只是转换为string
),因为排序顺序可能会受到你比较之前和/或之后的字符的影响,单个字符可能不是字形(并且订购可能不适用)。 一个例子:在捷克语中C出现在H之前然后你期望"ch".CompareTo("h") == -1
…错误,“ch”是有向图 ,它在H和我之间然后是"ch".CompareTo("h") == 1
!!! 更多关于这个更详细的post 。
顺序比较是不同的,因为来自ASCII的遗产(我试过的每种文化都返回了相同的结果)。 它们保留了ASCII排序以实现兼容性(并且更容易迁移到Unicode),但是对于字符串比较,它们必须遵守文化规则
一个更常见的例子是大写/小写字符(注意'和'来执行序数和文化感知比较):
'A'.CompareTo('a') != "A".CompareTo("a")
如果你这样做是为了执行文本搜索,那么我强烈建议你不要直接使用Char
比较,除非你知道文化问题(排序)和Unicode细节(代理和编码,主要)。
这是由于Char
和String
类中IComparable
方法CompareTo
实现不同
Char.cs
public int CompareTo(Char value) { return (m_value-value); }
String.cs
public int CompareTo(String strB) { return CultureInfo.CurrentCulture.CompareInfo.Compare(this, strB, 0); }
逻辑是文化感知的比较,它依赖于内部的InternalCompareString
。