This code:
Console.WriteLine("~".CompareTo("a") > 0);
Console.WriteLine('~'.CompareTo('a') > 0);
Gives me:
F开发者_JAVA技巧alse
True
WTF?
myChar.CompareTo(otherChar)
compares two characters merely by their unicode values.
myString.CompareTo(otherString)
uses a sort comparer of the current culture which may be implemented in a more lexical way.
Another way to show this behaviour is:
Console.WriteLine("a".CompareTo("b")); // -1
Console.WriteLine("b".CompareTo("a")); // 1
Console.WriteLine('a'.CompareTo('b')); // -1
Console.WriteLine('b'.CompareTo('a')); // 1
Console.WriteLine("~".CompareTo("a")); // -1
Console.WriteLine("a".CompareTo("~")); // 1
Console.WriteLine('~'.CompareTo('a')); // 29
Console.WriteLine('a'.CompareTo('~')); // -29
The difference may be subtle, but it is documented. The comparison in Char.CompareTo(Char)
is
based on the encoded values of this instance and value, not their lexicographical characteristics.
At the same time, the documentation for String.CompareTo(String)
performs a word (case-sensitive and culture-sensitive) comparison using the current culture.
I.e. the first one bases the comparison on order, the latter on the default rules in the current culture (the order you might see in a dictionary).
I think that myString.CompareTo(otherString)
returns the same value as CultureInfo.CurrentCulture.CompareInfo.Compare(myString,otherString,CompareOptions.None)
, i.e. does a culture-depending comparison.
In most cultures, non-alphabetic characters are sorted before letters, therefore '~'
comes before 'a'
.
'char.CompareTo(otherChar)` on the other hand just compares the unicode values (i.e. 97 for 'a' against 126 for '~') and therefore returns a different result.
To compare strings the same way as characters (by order of character code only) you have to use an ordinal comparison:
Console.WriteLine(String.Compare("~", "a", StringComparison.Ordinal) > 0);
Output:
True
精彩评论