我有一个已经解决的问题,但我不知道到底发生了什么。这是简化的任务:我有一个记录列表。记录包含2个字段,key
和value
。所有键都不同。我想对它们进行排序,所以
key
,应该在第一位。 value
包含"未找到密钥的行"按key
key
按字母顺序排列其余行。所以我做了这个课:
private class RecordComparer : IComparer<GridRecord>
{
public int Compare(GridRecord x, GridRecord y)
{
if (x.Key == String.Empty)
return -1;
else if (y.Key == String.Empty)
return 1;
else if (x.Value.Contains("Key not found:") && !y.Value.Contains("Key not found:"))
return -1;
else if (!x.Value.Contains("Key not found:") && y.Value.Contains("Key not found:"))
return 1;
else return (x.Key.CompareTo(y.Key));
}
}
当我尝试使用它时,我得到Comparer (or the IComparable methods it relies upon) did not return zero when Array.Sort called x. CompareTo(x). x: '' x's type: 'GridRecord' The IComparer:
错误并不总是出现,有时(通常在我第一次在我的程序中使用它)它工作正常。第二次或第三次呼叫崩溃。
插入
if (x.Key == y.Key)
return 0;
在上面的比较函数的开始解决了问题,一切正常。为什么呢?
答案 0 :(得分:1)
如果您将{Key=""}
与任何内容进行比较,那么您目前正在返回-1
。即使您将与自身进行比较。当你将某些东西与它自己(或者在语义上等同于它的东西)进行比较时,你应该返回0
。这就是错误所在。
答案 1 :(得分:0)
在自定义比较器中强制执行总订单是明智的。总顺序的要求之一是反身性:对于任何x
Compare(x, x)
必须等于零。例如,当comparer用于对具有非唯一值的数组进行排序时,此属性是必需的。
某些库可能会对自定义比较器进行额外检查。没有必要将元素与自身进行比较,但另一方面,这种检查允许运行时查找细微的错误(如您所做的那样)。可能这就是你收到错误信息的原因。修复此类错误可使您的代码更稳定。通常,这样的检查仅存在于调试版本中。