C#String比较不使用尾部斜杠

时间:2015-04-12 12:37:41

标签: c# c#-4.0

在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时,我遇到了这个问题。它很容易解决,但这是一个令人惊讶的问题。

3 个答案:

答案 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) {
    ...
}