哪里是不一致的IComparer这是导致空引用?这是、IComparer

2023-09-03 17:43:40 作者:凉城

我收到我的自定义IComparer实现空对象,尽管它被应用到集合中没有空条目。我的理解是,这可以通过在IComparer实现的不一致造成的。我不能当场在那里这可能发生在以下code。

I'm receiving a null object in my custom IComparer implementation despite no null entries in the collection it is being applied to. My understanding is this can be caused by inconsistencies in the IComparer implementation. I cannot spot where this could be happening in the following code.

有关引用的意图是,这些被'正确'属性进行排序,再如果它们是相同的,这种种基于tiebreakerDelta属性,该属性排序最接近零,而无需结束了。

For reference the intent is that these are sorted by the 'correct' property first, then if they are the same, it sorts based on the 'tiebreakerDelta' property, which sorts closest to zero without going over.

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

感谢您的帮助,您也许能提供!

Thanks for any help you might be able to offer!

修改:我敢肯定这是不是一个真正的空引用,它正在引起一些不一致的地方。此外,偶尔出现这种错误文本显示确认 -

EDIT: I am certain this is not a true null reference, it is being caused by some inconsistency. Also, occasionally this error text is displayed confirming -

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',

断点不帮我这个不幸的。

Breakpoints do not help me with this unfortunately.

编辑:下面是一个简单的例子,其中ResultsLineViewModel实现IFoolsSortable接口:

Here is a short example where ResultsLineViewModel implements the IFoolsSortable interface:

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

正确的排序因为这将是:1号线,3号线,2号线,4号线

The correct sort for this would be: Line1, line3, line2, line4

推荐答案

如果 A 大于 B 然后比较(A,B)应该返回1 比较(B,A)应该返回-1。如果你有 a.correct = b.correct ,都 a.tiebreakerDelta = 0 b.tiebreakerDelta = 0 ,因为要保留操作的顺序,那么这将不会是一致的比较方法。

If a is greater than b then Compare(a,b) should return 1 and Compare(b,a) should return -1. And if you have a.correct = b.correct, and both a.tiebreakerDelta = 0 and b.tiebreakerDelta = 0 then this won't be consistent to the Compare method because you want to retain the order of the operation.

据我所看到的,你首先应该做到这一点。

As far as I can see, you should first do this

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

,然后这样的:

and then this:

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。检查比如这个链接