问题描述
我在自定义 IComparer 实现中收到一个空对象,尽管它所应用的集合中没有空条目.我的理解是这可能是由 IComparer 实现中的不一致引起的.我无法在以下代码中发现这可能发生的位置.
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());
正确的排序是:Line1, line3, line2, line4
The correct sort for this would be: Line1, line3, line2, line4
推荐答案
如果 a
大于 b
则 Compare(a,b)
应该返回 1 并且 Compare(b,a)
应该返回 -1.如果你有 a.correct = b.correct
,并且有 a.tiebreakerDelta = 0
和 b.tiebreakerDelta = 0
那么这不会t 与 Compare
方法保持一致,因为您希望保留操作的顺序.
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
然后是这个:
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.检查例如这个 链接
Also note that your logic is reversed, if first is grater than second, you should return 1, not -1. Check for instance this link
这篇关于此 Icomparer 中导致空引用的不一致在哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!