何时对启用了可空引用类型的参数进行空值检查
When to null-check arguments with nullable reference types enabled
给定一个使用 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));
...
}
None 的代码是 public API 的一部分,所以我怀疑这些检查可能是多余的。这两个参数未标记为可空,因此如果任何调用代码可能传入空值,编译器应发出警告。
Given a function in a program using C# 8.0's nullable reference types feature, should I still be performing null checks on the arguments?
这取决于您对通过 API 的所有路径的确定程度。考虑这段代码:
public void Foo(string x)
{
FooImpl(x);
}
private void FooImpl(string x)
{
...
}
此处 FooImpl
不是 public API 的一部分,但如果 Foo
未验证 ,仍会收到空引用它的 参数。 (实际上,它可能依赖于 Foo
来执行参数验证。)
检查 FooImpl
当然不是 冗余 因为它在执行时执行检查编译器 不能 绝对在编译时确定。可空引用类型提高了一般安全性,更重要的是提高了代码的 表现力 ,但它们与 CLR 提供的类型安全性不同(阻止您处理 string
引用作为 Type
引用,例如)。编译器可以通过多种方式 "wrong" 判断特定表达式在执行时是否为 null,并且无论如何都可以用 !
覆盖编译器。
更广泛地说:如果您的检查在之前 C# 8 不是多余的,那么它们在之后 C# 8 也不是多余的,因为可空引用类型功能不会更改为代码生成的 IL,除了属性方面。
因此,如果您的 public API 正在执行所有适当的参数检查(上例中的 Foo
),那么代码中的检查就已经是多余的了。你对此有多大信心?如果您绝对有信心并且错误的影响很小,那么当然 - 摆脱验证。 C# 8 功能可能会帮助您获得信心,但您仍然需要小心不要 太 自信 - 毕竟 - 上面的代码不会给出任何警告。
就我个人而言,在为 C# 8 更新 Noda Time 时,我不会删除任何参数验证。
给定一个使用 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));
...
}
None 的代码是 public API 的一部分,所以我怀疑这些检查可能是多余的。这两个参数未标记为可空,因此如果任何调用代码可能传入空值,编译器应发出警告。
Given a function in a program using C# 8.0's nullable reference types feature, should I still be performing null checks on the arguments?
这取决于您对通过 API 的所有路径的确定程度。考虑这段代码:
public void Foo(string x)
{
FooImpl(x);
}
private void FooImpl(string x)
{
...
}
此处 FooImpl
不是 public API 的一部分,但如果 Foo
未验证 ,仍会收到空引用它的 参数。 (实际上,它可能依赖于 Foo
来执行参数验证。)
检查 FooImpl
当然不是 冗余 因为它在执行时执行检查编译器 不能 绝对在编译时确定。可空引用类型提高了一般安全性,更重要的是提高了代码的 表现力 ,但它们与 CLR 提供的类型安全性不同(阻止您处理 string
引用作为 Type
引用,例如)。编译器可以通过多种方式 "wrong" 判断特定表达式在执行时是否为 null,并且无论如何都可以用 !
覆盖编译器。
更广泛地说:如果您的检查在之前 C# 8 不是多余的,那么它们在之后 C# 8 也不是多余的,因为可空引用类型功能不会更改为代码生成的 IL,除了属性方面。
因此,如果您的 public API 正在执行所有适当的参数检查(上例中的 Foo
),那么代码中的检查就已经是多余的了。你对此有多大信心?如果您绝对有信心并且错误的影响很小,那么当然 - 摆脱验证。 C# 8 功能可能会帮助您获得信心,但您仍然需要小心不要 太 自信 - 毕竟 - 上面的代码不会给出任何警告。
就我个人而言,在为 C# 8 更新 Noda Time 时,我不会删除任何参数验证。