Comparer 使 Sort 何时会抛出 ArgumentException?

发布于 2024-07-10 20:01:33 字数 234 浏览 8 评论 0原文

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

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

The documentation for Sort says that Sort will throw an ArgumentException if "The implementation of comparer caused an error during the sort. For example, comparer might not return 0 when comparing an item with itself."

Apart from the example given, can anyone tell me when this would otherwise happen?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

后来的我们 2024-07-17 20:01:33

排序算法 (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 中参数异常。

这是坏 IComparer 的另一个例子

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

所以我想,简短的答案是,任何时候您的 IComparer 实现不能一致地比较文档中定义的值:

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

The sort algorithm (QuickSort) relies on a predictable IComparer implementation. After a few dozen layers of indirection in the BCL you end up at this method:

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));
    }
}

Going a bit further into the QuickSort implementation, you see code like this:

    while (comparer.Compare(keys[a], y) < 0)
    {
        a++;
    }
    while (comparer.Compare(y, keys[b]) < 0)
    {
        b--;
    }

Basically if the IComparer misbehaves the Quicksort call with throw an IndexOutOfRangeException, which is wrapped in n ArgumentException.

Here is another example of bad IComparer's

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

So I guess, the short answer is, anytime your IComparer implementation does not consistently compare values as defined in the documentation:

Compares two objects and returns a
value indicating whether one is less
than, equal to or greater than the
other.

无风消散 2024-07-17 20:01:33

我今天遇到了这个问题,经过调查,我发现有时调用我的比较器时 x 和 y 是对同一个对象的引用,并且我的比较器没有返回 0。修复后,我不再收到异常。

HTH,

埃里克

I ran into this today, and after investigating, I found that sometimes my comparer was being called with x and y being references to the same object, and my comparer was not returning 0. Once I fixed that, I stopped getting the exception.

HTH,

Eric

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文