Hof*_*ffs 5 c# .net-core c#-8.0 nullable-reference-types
C# 8 引入了可为空引用类型,这是一个非常酷的特性。现在,如果您希望获得可空值,则必须编写所谓的守卫:
object? value = null;
if (value is null)
{
throw new ArgumentNullException();
}
…
Run Code Online (Sandbox Code Playgroud)
这些可能有点重复。我想知道是否有可能避免为每个变量编写这种类型的代码,而是有一个保护类型的static void函数,如果 value is 则抛出异常,null或者如果 value is not 则返回null。或者这对编译器来说太难推断了?特别是如果它是外部库/包?
您可以做一些事情。
您可以[DoesNotReturnIf(...)]在您的守卫方法中使用,以指示它在特定条件为真或假时抛出,例如:
public static class Ensure
{
public static void True([DoesNotReturnIf(false)] bool condition)
{
if (!condition)
{
throw new Exception("!!!");
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后:
public void TestMethod(object? o)
{
Ensure.True(o != null);
Console.WriteLine(o.ToString()); // No warning
}
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为:
[DoesNotReturnIf(bool)]: 放置在 bool 参数上。如果参数具有指定的 bool 值,则无法访问调用后的代码
或者,您可以像这样声明一个保护方法:
public static class Ensure
{
public static void NotNull([NotNull] object? o)
{
if (o is null)
{
throw new Exception("!!!");
}
}
}
Run Code Online (Sandbox Code Playgroud)
并像这样使用它:
public void TestMethod(object? o)
{
Ensure.NotNull(o);
Console.WriteLine(o.ToString()); // No warning
}
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为:
[NotNull]:? 对于输出(引用/输出参数,返回值),即使类型允许,输出也不会为空。对于输入(按值/输入参数),当我们返回时,已知传递的值不是空的。
当然,真正的问题是你为什么要这样做。如果您不希望value成为null,则将其声明为object?,而不是object- 这就是拥有 NRT 的意义所在。