List.Sort ArgumentException error: IComparer does not return 0 (null)

I have the following problem and I can’t understand where it came from. I would really appreciate help.

Code:

List<Point> lst = new List<Point>(); lst.Add(new Point(0, -2)); lst.Add(new Point(-1, -2)); lst.Sort(delegate (Point x,Point y) { if (xX == 0) return -1; else if (yX == 0) return 1; else { double retVal1 = xY * 1.0 / -xX; double retVal2 = yY * 1.0 / -yX; int retVal = -Math.Sign(retVal1 - retVal2); return retVal; } }); 

If executed, I get an ArgumentException saying IComparer does not return 0 (null). However, in reality, it cannot return anything but -1, 0, and 1, or?

Many thanks for your help!

Ah, btw I'm using .NET 3.5

+4
source share
3 answers

In fact, the error message says: IComparer (or the IComparable methods it relies on) did not return zero when Array.Sort called x. Sotrage Too (x). x: '' x type: 'Point' IComparer: 'System.Array + FunctorComparer`1 [System.Drawing.Point]'.

You should return 0 if the objects are identical:

  lst.Sort(delegate(Point x, Point y) { if (xX == yX && xY == yY) { // you are missing this return 0; } if (xX == 0) return -1; else if (yX == 0) return 1; else { double retVal1 = xY * 1.0 / -xX; double retVal2 = yY * 1.0 / -yX; int retVal = -Math.Sign(retVal1 - retVal2); return retVal; } }); 
+8
source

You have not fully read Exception-Message. Most likely, he says that he does not return 0 for the same instance of the object.

Your code is incorrect, if the same instance of Point or an identical value is passed, it needs to return 0 . Otherwise, he will never know when he will finish sorting, and end with an endless loop ... and we all know that this is an absolute negative success.

+2
source

As said, the comparator must return 0 for the same value as identification entails equality (something is always equal to itself), and equality entails equivalence (you can order two different things equivalently, but you must order two equal element is equivalent).

There is one more problem: your check for .X equal to 0 can cause the same elements to return inconsistent ordering if both of them have .X equal to 0. This is an important rule that the comparison method should always be consistent in that :

If x <y, then y> x.

If x <y and y <z, then x <r.

Your algorithm breaks the first rule as follows:

Say that point a is {0, 3} and point b is {0, 2}

A call with (a, b) then returns -1, which means <b, but a call with (b, a) returns -1, which means b <a.

Replace all of this:

 lst.Sort(delegate (Point x,Point y) { return (xY * 1.0 / -xX).CompareTo(yY * 1.0 / -yX); }); 

(Note that this implicitly returns 0 for equal points - we could add an explicit check if this was a harder calculation as an optimization, but this is optional.

Also, Point is System.Drawing.Point here? If so, then this code is now fine, but if it is something else, it is worth noting that the code is fine if Point is a structure, but should contain a null check if Point is a class.

0
source

Source: https://habr.com/ru/post/1345540/


All Articles