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编码值( 4533 )。

字符串比较"-".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细节(代理和编码,主要)。

这是由于CharString类中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