C# list.Sort ArgumentException错误:IComparer不';t不返回0(null)

C# list.Sort ArgumentException错误:IComparer不';t不返回0(null),c#,c#-3.0,C#,C# 3.0,我有以下问题,我不知道它来自哪里。我非常感谢你的帮助 守则: 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 (x.X == 0) return -1; else if (y.X == 0) return 1

我有以下问题,我不知道它来自哪里。我非常感谢你的帮助

守则:

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 (x.X == 0)
        return -1;
    else if (y.X == 0)
        return 1;
    else
    {
        double retVal1 = x.Y * 1.0 / -x.X;
        double retVal2 = y.Y * 1.0 / -y.X;
        int retVal = -Math.Sign(retVal1 - retVal2);
        return retVal;
    }
});
List lst=new List();
第一次添加(新点(0,-2));
增加(新点(-1,-2));
一级排序(委托(点x、点y)
{
如果(x.x==0)
返回-1;
如果(y.X==0),则为else
返回1;
其他的
{
双retVal1=x.Y*1.0/-x.x;
双retVal2=y.y*1.0/-y.X;
int retVal=-Math.Sign(retVal1-retVal2);
返回返回;
}
});
如果执行,我会收到ArgumentException,说明IComparer不返回0(null)。但是,它实际上只能返回-1、0和1,或者

非常感谢你的帮助


啊,顺便说一句,我使用的是.NET3.5,您还没有完全阅读异常消息。它很可能表示,对于对象的同一实例,它不会返回0


您的代码错误,如果传入了相同的
点实例
或相同的值,则需要返回
0
。否则,他将永远不知道何时完成排序,并最终陷入无休止的循环…我们都知道这是一个绝对负面的性能影响。

实际上,错误消息说:当数组被称为x时,IComparer(或它所依赖的IComparable方法)没有返回零。比较(x)。x:'x的类型:'Point'图标比较程序:'System.Array+FunctorComparer'1[System.Drawing.Point]'

如果对象相同,则必须返回0:

    lst.Sort(delegate(Point x, Point y) {
        if (x.X == y.X && x.Y == y.Y) { // you are missing this
            return 0;
        }
        if (x.X == 0)
            return -1;
        else if (y.X == 0)
            return 1;
        else {
            double retVal1 = x.Y * 1.0 / -x.X;
            double retVal2 = y.Y * 1.0 / -y.X;
            int retVal = -Math.Sign(retVal1 - retVal2);
            return retVal;
        }
    });

如上所述,比较器必须为相同的值返回0,因为恒等式意味着相等(某事物总是等于它本身),相等意味着等价(您可以等价地排序两个不同的事物,但必须等价地排序两个相等的事物)

还有一个问题,如果您对.X的检查为0,则如果相同项目的.X都等于0,则可能会导致它们返回不一致的顺序。比较方法必须始终保持一致,这是一条重要规则:

如果xx

如果x 您的算法违反了第一条规则,因此:

假设点a是{0,3},点b是{0,2}

然后用(a,b)调用返回-1表示a 将整个事件替换为:

lst.Sort(delegate (Point x,Point y)
{
  return (x.Y * 1.0 / -x.X).CompareTo(y.Y * 1.0 / -y.X);
});
(请注意,这隐式返回0表示相等的点-如果这是一个较重的优化计算,我们可以添加一个显式检查,但这不是必需的


另外,这里是
Point
System.Drawing.Point
?如果是,那么这个代码现在就可以了,但是如果是其他代码,那么值得注意的是,如果
Point
是一个结构,那么这个代码就可以了,但是如果
Point
是一个类,那么应该包含一个空检查。

它不会返回0。你在哪里看到它呢?即使计算
else
块中的运算确实等于零,这是未知的。啊,好吧,对于相同的值,比较器必须是0。我不知道,谢谢你的回答!(事实上这很合乎逻辑,但我从来没有想到过)这仍然违反了下一个测试中的一致顺序,好像点a是{0,1},点b是{0,2},然后调用(a,b)返回-1表示a