比较器什么时候会进行排序抛出一个ArgumentException?
问题描述:
Sort的文档说Sort会抛出一个ArgumentException,如果“比较器的实现在排序过程中导致错误,例如,比较项与自身时,比较器可能不会返回0。比较器什么时候会进行排序抛出一个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));
}
}
进一步说有点进入快速排序的实现,你会看到这样的代码:
while (comparer.Compare(keys[a], y) < 0)
{
a++;
}
while (comparer.Compare(y, keys[b]) < 0)
{
b--;
}
基本上,如果在的IComparer抛出一个IndexOutOfRangeException异常的Quicksort调用,该异常包装在n个ArgumentException中。
这里是一个坏的IComparer的
class Comparer: IComparer<int>
{
public int Compare(int x, int y)
{
return -1;
}
}
所以我想,简单的答案是,任何时候你IComparer实现并不一致比较值,如文档中定义的另一个例子:
比较两个对象并返回一个 值,指示其中一个是否小于 ,等于或大于 其他。
答
我遇到了这个今天和调查后,我发现,有时候我比较器是被称为x和y是引用同一个对象,我的比较器没有返回0。一旦我固定的,我停止了例外。
HTH,
埃里克
谢谢 - 这几乎是我多远转向SO之前进行的。原来的错误似乎是IndexOutOfRangeException。这与比较器的可预测性有什么关系? – 2008-12-21 16:47:50
好的 - 我可以看到这可能是一个问题。谢谢! – 2008-12-21 16:56:39