3

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

除了给出的例子之外,谁能告诉我什么时候会发生这种情况?

4

2 回答 2

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 错误地执行 Q​​uicksort 调用并抛出一个 IndexOutOfRangeException,它包含在 n ArgumentException 中。

这是另一个坏 IComparer 的例子

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

所以我想,简短的回答是,只要您的 IComparer 实现不能始终如一地比较文档中定义的值:

比较两个对象并返回一个值,指示一个对象是否小于、等于或大于另一个对象。

于 2008-12-21T16:43:47.453 回答
3

我今天遇到了这个问题,经过调查,我发现有时我的比较器被调用时 x 和 y 是对同一个对象的引用,而我的比较器没有返回 0。一旦我修复了这个问题,我就停止了异常。

高温下,

埃里克

于 2011-10-11T19:04:33.080 回答