设计选择:我是否希望扩展方法在null上抛出异常?可能重复:C#:在扩展方法中验证“this”参数的最佳实践我对设计选择感到矛盾,想听听SO社区的意见。我在此处展示的示例只是必须做出此设计选择的一种可能情况——实际上,可能有更多情况。欢迎针对此特定案例和更一般的方法提供答案,也欢迎有关如何在特定案例中做出决定的指南。基本上,我想知道如何思考这个问题:当编写一个本质上不会失败的扩展方法时,如果将空引用作为this实例传递,是否应该对参数执行空检查?示例:我正在IEnumerable上编写一个扩展方法,它将遍历集合并执行一些操作——基本上,这就是它所做的:publicstaticvoidEach(thisIEnumerablecollection,Actionaction){foreach(vartincollection){action.Invoke(t);我无法决定的是,如果将null传递给任一参数,此扩展方法应该做什么。如果我不添加任何空值检查,我会在action.Invoke(T)上得到一个NullReferenceException,但是如果集合为空,for循环将默默地不执行任何操作(即使action也为空,也不会抛出任何异常。)。我决定添加一个null检查操作,这样我就可以抛出ArgumentNullException而不是NullReferenceException。但是我想用这个集合做什么?选项1:添加null检查,并抛出ArgumentNullException。选项2:只是默默地让该方法不执行任何操作。我认为将来使用这种方法会更有用吗?为什么?如果在LINQ中调用的集合为空,Microsoft将抛出ArgumentNullException。这实际上更像是一种风格问题,但与扩展方法的行为方式一致。@m0sa是对的,但是您会得到foreach的空引用,但我会说检查顶部并抛出ArgumentNullException。然后你可以用LINQ做同样的事情。例如,如果您查看反编译器中的Any(),您会看到:publicstaticboolAny(thisIEnumerablesource){if(source==null){throwError.ArgumentNull("source");}使用(IEnumeratorenumerator=source.GetEnumerator()){if(enumerator.MoveNext()){returntrue;}}返回假;您绝对应该进行null检查并抛出ArgumentNullException以避免在难以理解的代码中出现NullReferenceExceptions。一般来说,我会避免将null视为en"empty"IEnumerable。只需使用Enumerable.Empty()来避免空集合的特殊情况。如果您决定在扩展方法中进行空检查,您应该考虑“急切”。如果您在扩展方法中使用yieldreturn,则在迭代开始之前不会对其进行实际评估。您将扩展方法分成两部分。检查参数的“eager”部分和yieldreturn元素的“lazy”部分。首先:我很确定如果集合为空,将会出现NullReferenceException。所以你的部分问题完全没问题。关于其余部分:您是否通过检查null并抛出不同的异常来获得任何收益?在我看来:不会!所以我不会用根本没有帮助的检查来混淆我的代码。如果集合参数为null,我将抛出NullReferenceException。这是由于考虑如果它为null时它的行为方式,并且Each恰好只是一个常规方法-抛出NullReferenceException是我期望发生的事情。编辑:根据马丁的评论和对此的一些进一步研究,我收回我所说的话。在这种情况下,似乎不应抛出NullReferenceException,因为Microsoft建议改用ArgumentNullException。以上是C#学习教程:designchoice:doIwanttheextensionmethodtothrowanexceptiononnull?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
