代码之家  ›  专栏  ›  技术社区  ›  Brian Rasmussen

比较器何时使排序引发ArgumentException?

  •  3
  • Brian Rasmussen  · 技术社区  · 16 年前

    文件 Sort 表示如果“比较器的实现在排序过程中导致错误”,排序将引发ArgumentException。例如,比较项与自身时,比较器可能不会返回0。“

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

    2 回复  |  直到 13 年前
        1
  •  4
  •   Greg Dean    16 年前

    排序算法(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中。

    下面是另一个坏的比较者的例子

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

    因此,我想,简短的答案是,只要您的IComparer实现不一致地比较文档中定义的值:

    比较两个对象并返回 指示是否小于1的值 大于、等于或大于 其他。

        2
  •  3
  •   Eric Hill    13 年前

    我今天偶然发现了这个,在调查之后,我发现有时我的比较者被打电话来,X和Y是指 同一对象 ,我的比较器没有返回0。一旦我解决了这个问题,我就不再得到例外了。

    HTH

    埃里克