在C#4.0中,每当我比较两个有一个或多个尾部斜杠的字符串时,比较结果都不正确:
String a = "1/2.1/";
String b = "1/2/";
if (a.CompareTo(b) > 0)
MessageBox.Show("Correct: " + a + " > " + b);
else
MessageBox.Show("Not correct: " + a + " <= " + b);
a = a.TrimEnd('/');
b = b.TrimEnd('/');
if (a.CompareTo(b) > 0)
MessageBox.Show("Trailing slash removed. Correct: " + a + " > " + b);
else
MessageBox.Show("Trailing slash removed. Not correct: " + a + " <= " + b);
从词汇上讲,&#34; 1 / 2.1 /&#34;在&#34; 1/2 /&#34;之后出现,对此没有太多疑问。
在其他地方也会发生此行为,例如使用Select方法对数据表进行排序。
我做错了吗?或者这是.Net中的错误? 它甚至不应该与文化特定的信息等有关,因为斜杠是最基本的US ASCII字符集的一部分。
在比较SQL Server hierarchyID时,我遇到了这个问题。它很容易解决,但这是一个令人惊讶的问题。
答案 0 :(得分:1)
如果我在C中的旧技能没有让我失望,我认为CompareTo会逐字符地减去字符的Integer值,直到结果不为零。
在前三个相同的字符之后,CompareTo会查看第四个字符,这是第一个字符串的一个点和第二个字符串的斜杠。
点字符的整数值为46,而斜杠的整数值为47,46-47给出-1,因此“1 / 2.1 /”小于“1/2 /”。
答案 1 :(得分:1)
从字面上讲,“1 / 2.1 /”是在“1/2 /”之后出现的,对此没有太多疑问。
为什么会这样?在ASCII chart上,/
紧随.
之后。
鉴于以下两个字符串,它们相等,直到达到第4个字符。然后比较/
和.
,/
更大。所以你看到的结果(a < b
)实际上是正确的。
1/2.1/
1/2/
在致电TrimEnd()
后,您最终得到两个不同的字符串,其中a > b
。
1/2.1
1/2
答案 2 :(得分:1)
如果数字是右对齐的,您可以比较包含数字的字符串:
01/02.00/
01/02.10/
01/10.00/
如果无法做到这一点,请考虑为您的数字创建一个类型
public class ChapterNumber : IComparable<ChapterNumber>
{
private readonly decimal[] _number;
public ChapterNumber(params decimal[] number)
{
_number = number;
}
public int CompareTo(T obj)
{
var other = obj as ChapterNumber;
if (other == null) {
return +1;
}
int len = Math.Min(_number.Length, other._number.Length);
for (int i = 0; i < len; i++) {
int result = _number[i].CompareTo(other._number[i]);
if (result != 0) {
return result;
}
}
return _number.Length.CompareTo(other._number.Length);
}
public override ToString()
{
return String.Join('/', _number) + "/";
}
}
用法:
var a = new ChapterNumber(1, 2.1m);
var b = new ChapterNumber(1, 2);
if (a.CompareTo(b) > 0) {
...
}