.net 比较器何时使排序引发ArgumentException?
的文档说明,如果“comparer的实现在排序过程中导致错误,则排序将引发ArgumentException。例如,comparer在将项与自身进行比较时可能不会返回0。” 除了给出的示例外,有人能告诉我什么时候会发生这种情况吗?排序算法(快速排序)依赖于可预测的IComparer实现。在BCL中经过几十层间接寻址后,您将使用以下方法:.net 比较器何时使排序引发ArgumentException?,.net,sorting,icomparer,.net,Sorting,Icomparer,的文档说明,如果“comparer的实现在排序过程中导致错误,则排序将引发ArgumentException。例如,comparer在将项与自身进行比较时可能不会返回0。” 除了给出的示例外,有人能告诉我什么时候会发生这种情况吗?排序算法(快速排序)依赖于可预测的IComparer实现。在BCL中经过几十层间接寻址后,您将使用以下方法: public void Sort(T[] keys, int index, int length, IComparer<T> comparer) {
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));
}
}
public void排序(T[]键、int索引、int长度、IComparer比较器)
{
尝试
{
...
快速排序(键,索引,索引+(长度-1),比较器);
}
捕获(IndexOutOfRangeException)
{
...
抛出新的ArgumentException(Environment.GetResourceString(“Arg_BogusIComparer”,values));
}
}
进一步研究快速排序实现,您会看到如下代码:
while (comparer.Compare(keys[a], y) < 0)
{
a++;
}
while (comparer.Compare(y, keys[b]) < 0)
{
b--;
}
while(comparer.Compare(键[a],y)<0)
{
a++;
}
while(comparer.Compare(y,键[b])<0)
{
b--;
}
基本上,如果IComparer使用抛出一个IndexOutOfRangeException来错误地执行快速排序调用,该异常被包装在n ArgumentException中
这是另一个坏的IComparer的例子
class Comparer: IComparer<int>
{
public int Compare(int x, int y)
{
return -1;
}
}
类比较器:IComparer
{
公共整数比较(整数x,整数y)
{
返回-1;
}
}
因此,我想,简单的答案是,只要您的IComparer实现没有按照文档中的定义一致地比较值:
比较两个对象并返回一个
值,该值指示一个值是否小于
大于、等于或大于
其他的
今天我遇到了这个问题,在调查之后,我发现有时调用比较器时,x和y是对同一对象的引用,而我的比较器没有返回0。一旦我解决了这个问题,我就不再得到异常 嗯,
埃里克谢谢——这差不多就是我在开始这么做之前所取得的成绩。最初的错误似乎是一个IndexOutOfRangeException。这与比较器的可预测性有什么关系?好吧,有了它,我可以看出这可能是个问题。谢谢我对此做了更多的调查。如果我没有弄错的话,比较器在大多数情况下都是非常脆弱的。只有当上面的索引超出数组的边界时,问题才会出现。很明显,这几乎没有用,因为比较器应该做正确的事情。很好,Eric,我想这正是我所涉及的问题。非常感谢你的帮助!