我有一个tblDetail对象列表。 tblDetails有txtTracked,一个字符串。我想根据这个属性进行排序。所以我这样做:
switch (sortby)
{
//...
case "Tracked Y/N":
list.Sort((lhs, rhs) => {
return lhs.txtTracked.CompareTo(rhs.txtTracked);
});
break;
case "Tracked Y/N-desc":
list.Sort((lhs, rhs) => {
return -lhs.txtTracked.CompareTo(rhs.txtTracked);
});
break;
//...
}
除非有时txtTracked为null。好的,很好,所以我这样做:
switch (sortby)
{
//...
case "Tracked Y/N":
list.Sort((lhs, rhs) => {
string toCompare = lhs.txtTracked;
if (toCompare == null)
toCompare = "";
return toCompare.CompareTo(rhs.txtTracked);
});
break;
case "Tracked Y/N-desc":
list.Sort((lhs, rhs) => {
string toCompare = lhs.txtTracked;
if (toCompare == null)
toCompare = "";
return -toCompare.CompareTo(rhs.txtTracked);
});
break;
//...
}
常规升序排序工作正常,但出于某种原因,当我在同一组数据上使用降序排序时,我在"跟踪Y / N-desc&#34中的lhs上得到空引用异常;。所以我这样做:
switch (sortby)
{
//...
case "Tracked Y/N":
list.Sort((lhs, rhs) => {
string toCompare = lhs.txtTracked;
if (toCompare == null)
toCompare = "";
return toCompare.CompareTo(rhs.txtTracked);
});
break;
case "Tracked Y/N-desc":
//for some reason this sort adds null into the list. wat.
list.Sort((lhs, rhs) => {
if (lhs == null)
return 1;
if (rhs == null)
return -1;
string toCompare = lhs.txtTracked;
if (toCompare == null)
toCompare = "";
return -toCompare.CompareTo(rhs.txtTracked);
});
list.RemoveAll(d => d == null);
break;
//...
}
现在我收到一个新错误:
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.
是什么给出的?它的工作方式很好,但不是另一种方式。 C#如何确定我的排序功能不够好,我怎样才能做到正确?
另外,当我调用sort时,为什么null会被添加到我的列表中?
答案 0 :(得分:1)
到目前为止,您很幸运升序并没有抛出空引用异常。或者应该这样,你还没有引起你的注意。
您的一个(或多个)对象为null。当您使用升序排序时,它恰好出现在rhs上,并且在降序排列时出现了lhs。 rhs == null是可以的,因为CompareTo
方法可以解决这个问题。但是如果lhs == null,你会得到一个例外。
已经存在一种空安全方法,它允许lhs和rhs中的一个/两个为空:静态String.Compare(String, String)
。您可以将此方法与null-safe navigation operator ?.一起使用,如下所示:
list.Sort((lhs, rhs) => { return String.Compare(lhs?.txtTracked, rhs?.txtTracked); });
用于升序排序,
list.Sort((lhs, rhs) => { return String.Compare(rhs?.txtTracked, lhs?.txtTracked); });
降序排序。
答案 1 :(得分:1)
您:
list.Sort((lhs, rhs) => {
if (lhs == null)
return 1;
if (rhs == null)
return -1;
// more cases
});
这不起作用,因为如果两个比较都是null
,它将始终返回正数。因此排序算法永远不会正确。一旦它交换了两个null
,因为它们的顺序错误,例如它们仍然是错误的顺序。
如果x
与y
相比不是零,那么您提出的问题与y
相比,x
的符号必须相反。
相反,你可以这样做:
list.Sort((lhs, rhs) => {
if (lhs == null || rhs == null)
return Comparer<object>.Default.Compare(rhs, lhs);
return string.Compare(rhs.txtTracked, lhs.txtTracked);
});
如果其中一个或两个是null
,我只是将它们作为对象进行比较。那可行。你也可以用另一种方式写它:
list.Sort((lhs, rhs) => {
if (lhs == null || rhs == null)
return (rhs != null).CompareTo(lhs != null);
return string.Compare(rhs.txtTracked, lhs.txtTracked);
});
这种方式使用了false
小于true
的事实。
答案 2 :(得分:-1)
尝试切换desc的变量。
list.Sort((lhs, rhs) => {
return (rhs.txtTracked ?? "").CompareTo(lhs.txtTracked ?? "");
});