ASCII比较和字符串比较之间的区别

时间:2014-07-25 07:50:51

标签: c# string-comparison

我正在使用C#。当我比较两个char值时,它向我发送正确的输出,例如,

'-'.CompareTo('!') //Its sending me positive value 12

表示' - '> '!' true

但是当我比较两个相同值的字符串时,它会向我发送不同的结果

"-".CompareTo("!") //Its sending me negative value -1

表示“ - ”> “!” false

任何人都可以解释一下为什么会这样做吗?这两种情况都不应该是“真的”吗?

3 个答案:

答案 0 :(得分:7)

字符串的比较方法是特定于文化的。这就是你得到不同结果的原因。改为使用string.CompareOrdinal,这是逐字节比较。

var v = '-'.CompareTo('!');//12
var s = string.CompareOrdinal("-", "!");//12

Best Practices for Using Strings in the .NET Framework

答案 1 :(得分:4)

此比较'-'.CompareTo('!')将执行序数比较。它将比较数字UTF-16编码值(4533)。

字符串比较"-".CompareTo("!")不同,它会执行文化感知比较。这意味着,无论数值如何,字符都将根据当前文化的排序规则进行排序

您可以尝试使用字符串的序数比较:

String.CompareOrdinal("-", "!")

这将对字符串执行序数比较,然后您将获得相同的结果(12)。

您无法在Char上执行(真实)文化感知比较(如果您需要,只需转换为string),因为排序顺序可能会受到字符影响之前和/或在您进行比较之后,单个字符可能不是字形(并且订购可能不适用)。一个例子:在捷克语中 C 出现在 H 之前,那么你期望"ch".CompareTo("h") == -1 ...错误," ch"是 digraph ,它在 H I 之间,然后是"ch".CompareTo("h") == 1!有关详情,请参阅this more detailed post

顺序比较不同仅仅是因为来自ASCII的遗产(我尝试的每种文化都返回了相同的结果)。他们保留了ASCII排序以实现兼容性(并且更容易迁移到Unicode),但是为了进行字符串比较,他们必须遵守文化规则。

一个更常见的例子是大写/小写字符(注意' " 来执行序数和文化 - 意识到比较):

'A'.CompareTo('a') != "A".CompareTo("a")

如果您正在执行此操作以执行文本搜索,那么我强烈建议您不要直接使用Char比较,除非您了解文化问题(订购) )和Unicode细节(代理和编码,主要)。

答案 2 :(得分:1)

这是由于IComparableCompareTo类中Char方法String的实施方式存在差异

  

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