【发布时间】:2019-06-28 19:32:13
【问题描述】:
给定程序中使用 C# 8.0 的可空引用类型功能的函数,我是否仍应对参数执行空检查?
void Foo(string s, object o)
{
if (s == null) throw new ArgumentNullException(nameof(s)); // Do I need these?
if (o == null) throw new ArgumentNullException(nameof(o));
...
}
这些代码都不是公共 API 的一部分,所以我怀疑这些检查可能是多余的。这两个参数没有标记为可空,因此编译器应该警告任何调用代码可能传入空。
【问题讨论】:
-
如果您可以控制将调用此方法的整个代码库,并且所有代码库都是使用启用此功能的 C# 8 编译的,并且 你很勤奋并修复了编译器产生的所有警告/错误,那么你可以删除那些 if 语句。如果您不确定这些要求中的任何一个,那么您应该保留 if 语句。
-
通过现在已删除的答案中的 cmets,我很清楚,您并不是想了解编译器检查,而是询问其他人的观点。因此,我主要基于意见投票决定结束这个问题。正如答案和那些 cmets 中所述,编译器检查不能替代 if 语句或合同系统,并且很容易绕过。这种风险对您来说是否足够完全取决于您。但是,您似乎已经知道新的编译器检查的作用。
-
我使用 JetBrains Annotations 和 ReSharper/Rider 已经有一段时间了,它们可以帮助您确信您的代码正在做正确的事情,但它们不能替代实际检查所以我都有。在可空引用类型出现后,我将继续使用这两种方法,因为我编写的代码可能会被未经这些检查编译的代码所消耗,或者该代码的编写者甚至可能完全对编译器撒谎。 (众所周知,当我觉得需要时,我会到处使用奇怪的技巧)。
-
编译器无法对 any 调用代码发出真正的警告——存在会阻碍其分析的转义舱口和覆盖(如 null-forgiving 运算符)。您是否添加这些检查应该在很大程度上独立于您是否使用可为空的引用——如果您已经确信没有它们,您可以继续不使用它们;如果你没有,那么你可能应该把它们留在里面。新的检查降低了引入错误的可能性。它们是否使您不再需要它们不太可能将取决于。
-
@LasseVågsætherKarlsen 这是明确鼓励的基于意见的问题。这是
Many good questions generate some degree of opinion based on expert experience。在这个时间点,很多人都知道该功能的描述,但很少有人知道实际编译器限制。更少有迁移大型项目以使用可为空引用的经验。我可以说出 3 个名字,其中一个已经回答了。另外两人在 SO
标签: c# c#-8.0 nullable-reference-types