Sort的文档说,如果“比较器的实现在排序过程中导致错误。例如,比较器在将项目与自身进行比较时可能不会返回 0”,Sort 将抛出 ArgumentException。
除了给出的例子之外,谁能告诉我什么时候会发生这种情况?
排序算法 (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 实现不能始终如一地比较文档中定义的值:
比较两个对象并返回一个值,指示一个对象是否小于、等于或大于另一个对象。
我今天遇到了这个问题,经过调查,我发现有时我的比较器被调用时 x 和 y 是对同一个对象的引用,而我的比较器没有返回 0。一旦我修复了这个问题,我就停止了异常。
高温下,
埃里克