Comparer何时使Sort抛出ArgumentException?

时间:2008-12-21 16:32:26

标签: .net sorting icomparer

Sort的文档说如果“比较器的实现在排序过程中导致错误,则Sort会抛出ArgumentException。例如,在比较项目时,comparer可能不会返回0。”

除了给出的例子,有人能告诉我何时会发生这种情况?

2 个答案:

答案 0 :(得分:4)

排序算法(QuickSort)依赖于可预测的IComparer实现。在BCL中进行了几十个间接层后,你最终得到了这个方法:

public void Sort(T[] keys, int index, int length, IComparer<T> comparer)
{
    try
    {
        ...
        ArraySortHelper<T>.QuickSort(keys, index, index + (length - 1), comparer);

    }
    catch (IndexOutOfRangeException)
    {
        ...
        throw new ArgumentException(Environment.GetResourceString("Arg_BogusIComparer", values));
    }
}

进一步了解QuickSort实现,您会看到如下代码:

    while (comparer.Compare(keys[a], y) < 0)
    {
        a++;
    }
    while (comparer.Compare(y, keys[b]) < 0)
    {
        b--;
    }

基本上,如果IComparer错误地使用Quicksort调用抛出一个IndexOutOfRangeException,它包含在n ArgumentException中。

这是另一个不好的IComparer的例子

class Comparer: IComparer<int>
{
    public int Compare(int x, int y)
    {
        return -1;
    }
}

所以我想,简单的答案是,只要您的IComparer实现没有始终如一地比较文档中定义的值:

  

比较两个对象并返回一个   指示一个是否更少的值   比,等于或大于   其他

答案 1 :(得分:3)

我今天碰到了这个,经过调查,我发现有时我的比较器被调用x和y被引用同一个对象,而我的比较器没有返回0.一旦我修好了,我停止了例外。

HTH,

埃里克