如何在 C# 中使用 IComparer 接口排序时克服 ArgumentException?

How to overcome the ArgumentException while sorting using the IComparer interface in C#?

我正在使用 IComparer 对 RowRanges 数组进行排序。当行范围达到 16 时,它工作正常。超过 16,发生异常,说明未执行 排序并抛出异常,说明无法执行排序,因为值与自身和值相比与 other 反复比较。在调试的时候,我发现这个问题是在拿对象进行比较的时候出现的。但是这个异常是如何在 16 之后发生的,而它在 16 之前都可以正常工作?请参考以下代码片段。

internal class ColComparer : IComparer
{

    public int Compare(object a, object b)
    {
        if (a == null || b == null)
        {
            return System.Collections.Comparer.Default.Compare(a, b);
        }

    GridRangeInfo r0 = (GridRangeInfo)a;
    GridRangeInfo r1 = (GridRangeInfo)b;

    if (r0 == r1)
    {
        return 0;
    }
    else
    {
        if (r0.RangeType == GridRangeInfoType.Table)
        {
            return -1;
        }
        else if (r1.RangeType == GridRangeInfoType.Table)
        {
            return 1;
        }
        else if (r0.RangeType == GridRangeInfoType.Rows)
        {
            return -1;
        }
        else if (r1.RangeType == GridRangeInfoType.Rows)
        {
            return 1;
        }
        else if (r0.Left != r1.Left)
        {
            return r0.Left - r1.Left;
        }
        else if (r0.Right != r1.Right)
        {
            return r0.Right - r1.Right;
        }
        else if (r0.Top != r1.Top)
        {
            return r0.Top - r1.Top;
        }
        else
        {
            return r0.Bottom - r1.Bottom;
        }
    }
}
}


class SortArray 
{
    //Array Data
    //

    GridRangeInfo[] ranges = new GridRangeInfo[this.Count];                 
    Array.Sort(ranges, new GridRangeInfo.ColComparer());
 }

让我知道异常发生的位置,并分享您解决此问题的想法。

提前致谢,

辛杜

r0.RangeType == GridRangeInfoType.Table .. return -1 等条件会产生 不稳定的 结果。这是因为它取决于"which"项是r0和r1。

遵循与函数其余部分相同的 if-then-return 模式 - 其中 r0.X 与 r1.X 进行比较,然后 'something is done based on that'.

例如

    if (r0.RangeType != r1.RangeType) {
    {
        if (r0.RangeType == GridRangeInfoType.Table) {
           return -1; // r0 first - prioritize 'Table' range types
        } else {
           return 1; // r1 first
        }
    }