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,则可能会导致它们返回不一致的顺序。比较方法必须始终保持一致,这是一条重要规则: 如果x
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