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.
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.
EDIT: 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());
The correct sort for this would be: Line1, line3, line2, line4