C#中的List.Sort:使用空对象调用比较器由于某种原因,它有时会调用比较器类的Compare方法,并将空对象作为参数之一。但是,如果我用调试器检查列表,则集合中没有空对象。我的比较器类如下所示:publicclassDelegateToComparer:IComparer{privatereadonlyFunc_comparer;publicintCompare(Tx,Ty){return_comparer(x,y);}publicDelegateToComparer(Funccomparer){_comparer=comparer;这允许将委托传递给List.Sort方法,如下所示:mylist.Sort(newDelegateToComparer((x,y)=>{returnx.SomeProp.CompareTo(y.SomeProp);});因此,上面的委托为x参数抛出一个空引用异常,即使mylist的任何元素都不是null。更新:是的,我绝对相信它是抛出空引用异常的参数x!更新:我没有使用框架的列表。排序方法,而不是尝试自定义排序方法(即newBubbleSort().sort(mylist)),问题就消失了。正如我所怀疑的那样,List.Sort方法出于某种原因将null传递给比较设备。当比较函数不一致时会出现问题,所以xusingSystem.Collections.Generic;类程序{staticvoidMain(){varletters=newList{"B","C","A"};letters.Sort(比较字符串);}privatestaticintCompareStrings(stringl,stringr){if(l=="B")return-1;返回l.CompareTo(r);你确定问题不是SomeProp为空吗?特别是,使用字符串或Nullable值。对于字符串,最好使用:list.Sort((x,y)=>string.Compare(x.SomeProp,y.SomeProp));(编辑)对于空安全包装器,您可以使用Comparer.Default-例如,按属性对列表进行排序:使用系统;使用System.Collections.Generic;publicstaticclassListExt{publicstaticvoidSort(thisListlist,Funcselector){if(list==null)thrownewArgumentNullException("list");如果(选择器==null)抛出新的ArgumentNullException(“选择器”);varcomparer=Comparer.Default;list.Sort((x,y)=>comparer.Compare(selector(x),selector(y)));}}classSomeType{publicoverridestringToString(){returnSomeProp;}publicstringSomeProp{get;放;}staticvoidMain(){varlist=newList{newSomeType{SomeProp="def"},newSomeType{SomeProp=null},newSomeType{SomeProp="abc"},newSomeType{SomeProp="ghi"},};列表。排序(x=>x.SomeProp);列表。ForEach(控制台。WriteLine);我也有这个问题(将空引用传递给我的自定义IComparer实现),结果发现问题是由于使用了不一致的比较函数。这是我原来的IComparer实现:如果(!float.TryParse(x,outxNumber)){返回-1;}if(!float.TryParse(y,outyNumber)){return-1;}如果(xNumber==yNumber){返回0;}else{返回(xNumber>yNumber)?1:-1;这段代码中的bug在于,每当无法正确解析其中一个值时,Compare就会返回-1(在我的例子中,这是由于数值的字符串表示格式错误,因此TryParse总是失败)。请注意,调用Compare(x,y)和Compare(y,x)将产生相同的结果:-1如果x和y的格式都不正确(因此TryParse都失败)。我认为这是主要问题。在调试时,Compare()在某个时候将空字符串指针作为其参数之一传递,即使正在排序的集合不包含空字符串。一旦我修复了TryParse问题并使我的实现保持一致,问题就消失了,并且不再向Compare传递空指针。马克的回答很有用。我同意他的观点,即NullReference是由于在null属性上调用CompareTo。您可以不扩展类,而是:mylist.Sort((x,y)=>(Comparer.Default.Compare(x.SomeProp,y.SomeProp)));其中SomePropType是SomeProp的类型出于调试目的,您希望该方法是null安全的。(或者至少捕获null-ref.exception,并以某种硬编码方式处理它)。然后,使用调试器查看其他值如何比较,以什么顺序比较,以及哪些调用成功或失败。然后你会找到你的答案,然后你可以删除空安全。你能运行这段代码吗?mylst.Sort((i,j)=>{Debug.Assert(i.SomeProp!=null&&j.SomeProp!=null);returni.SomeProp.CompareTo(j.SomeProp);});我自己无意中发现了这个问题,发现它与我输入的NaN属性有关。这是一个应该产生异常的最小测试用例:以上是C#学习教程:List.SortinC#:Callingcomparerwithanullobject,希望大家多多关注——publicclassC{doublev;publicstaticvoidMain(){vartest=newList{newC{v=0d},newC{v=Double.NaN},newC{v=1d}};test.Sort((d1,d2)=>(int)(d1.v-d2.v));}}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
