此Icomparer中导致空引用的不一致性在哪里?

时间:2012-11-15 22:31:53

标签: c# .net compare icomparable icomparer

我在自定义IComparer实现中收到一个空对象,尽管它正在应用的集合中没有空条目。我的理解是这可能是由IComparer实现中的不一致引起的。我无法在下面的代码中找到这可能发生的地方。

作为参考,目的是首先按“正确”属性对它们进行排序,然后如果它们相同,则根据“tiebreakerDelta”属性进行排序,该属性最接近零排序而不会过去。

        public int Compare(IFoolsSortable a, IFoolsSortable b)
    {
        int value1 = a.correct;
        int value2 = b.correct;

        // compare the total correct first
        if (value1 < value2) return 1;
        if (value1 > value2) return -1;

        // total correct is the same, sort on deltas (closest without going over)
        value1 = a.tiebreakerDelta;
        value2 = b.tiebreakerDelta;

        // returning -1 says "put value1 higher in the list than value2" 
        // (higher means closer to the 0 element of the sorted array) 
        if (value1 == 0) return -1; // a zero is higher than anything! 
        if (value2 == 0) return 1; // ditto, for the other arg, if val1 isn't zero 
        if (value1 == value2) return 0; // after that, if they are the same, say so 
        // if both are negative, then the larger one goes higher 
        if (value1 < 0 && value2 < 0) return (value1 > value2) ? -1 : 1;
        // if only one is negative, it goes higher 
        if (value1 < 0) return -1;
        if (value2 < 0) return 1;
        // finally, if both are postitive, lower one goes higher 
        return (value1 > value2) ? 1 : -1;
    }

感谢您提供的任何帮助!

编辑:我确定这不是真正的空引用,它是由一些不一致引起的。此外,有时会显示此错误文本确认 -

Unable to sort because the IComparer.Compare() method returns inconsistent results. Either a value does not compare equal to itself, or one value repeatedly compared to another value yields different results. x: '',  x's type: 'ResultsLineViewModel',

不幸的是,断点并没有帮助我。

编辑:以下是ResultsLineViewModel实现IFoolsSortable接口的简短示例:

List<ResultsLineViewModel> ls = new List<ResultsLineViewModel>();
        ResultsLineViewModel line1 = new ResultsLineViewModel();
        line1.correct = 10;
        line1.tiebreakerDelta = 0;
        ls.Add(line1);

        ResultsLineViewModel line2 = new ResultsLineViewModel();
        line2.correct = 10;
        line2.tiebreakerDelta = 2;
        ls.Add(line2);

        ResultsLineViewModel line3 = new ResultsLineViewModel();
        line3.correct = 10;
        line3.tiebreakerDelta = -3;
        ls.Add(line3);

        ResultsLineViewModel line4 = new ResultsLineViewModel();
        line4.correct = 9;
        line4.tiebreakerDelta = 0;
        ls.Add(line4);

        ls.Sort(new FoolsSort());

对此的正确排序是:Line1,line3,line2,line4

1 个答案:

答案 0 :(得分:16)

如果a大于b,则Compare(a,b)应返回1,Compare(b,a)应返回-1。如果您有a.correct = b.correcta.tiebreakerDelta = 0b.tiebreakerDelta = 0,那么这与Compare方法不一致,因为您希望保留操作的顺序。

据我所见,你应该先做这个

if (value1 == value2) return 0; // after that, if they are the same, say so

然后这个:

if (value1 == 0) return -1; // a zero is higher than anything! 
if (value2 == 0) return 1; // ditto, for the other arg, if val1 isn't zero 

另请注意,您的逻辑是相反的,如果第一个比第二个更大,则应返回1,而不是-1。检查例如link