我正在使用C#。当我比较两个char值时,它向我发送正确的输出,例如,
'-'.CompareTo('!') //Its sending me positive value 12
表示' - '> '!'是 true
但是当我比较两个相同值的字符串时,它会向我发送不同的结果
"-".CompareTo("!") //Its sending me negative value -1
表示“ - ”> “!”是 false
任何人都可以解释一下为什么会这样做吗?这两种情况都不应该是“真的”吗?
答案 0 :(得分:7)
字符串的比较方法是特定于文化的。这就是你得到不同结果的原因。改为使用string.CompareOrdinal
,这是逐字节比较。
var v = '-'.CompareTo('!');//12
var s = string.CompareOrdinal("-", "!");//12
答案 1 :(得分:4)
此比较'-'.CompareTo('!')
将执行序数比较。它将比较数字UTF-16编码值(45
和33
)。
字符串比较"-".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)
这是由于IComparable
和CompareTo
类中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
。