可以将外部功能用作可空防护吗? [英] Possibility of external functions as nullable guards?
问题描述
C#8引入了可为空的引用类型,这是一个非常酷的功能。现在,如果您希望获得可为空的值,则必须编写所谓的防护:
C# 8 introduced nullable reference types, which is a very cool feature. Now if you expect to get nullable values you have to write so-called guards:
object? value = null;
if (value is null)
{
throw new ArgumentNullException();
}
…
这些可能有点重复。我想知道的是,是否有可能避免为每个变量编写这种类型的代码,而是有一个防护类型的 static void
函数,如果value null
或仅返回,如果值不是 null
。还是编译器难以推断?尤其是如果它是外部库/软件包?
These can be a bit repetitive. What I am wondering is if it is possible to avoid writing this type of code for every variable, but instead have a guard-type static void
function that throws exception if value is null
or just returns if value is not null
. Or is this too hard for compiler to infer? Especially if it's external library/package?
推荐答案
您可以做一些事情。
您可以在警卫方法中使用 [DoesNotReturnIf(...)]
来指示特定条件为真还是假时抛出该异常,例如:
You can use [DoesNotReturnIf(...)]
in your guard method, to indicate that it throws if a particular condition is true or false, for example:
public static class Ensure
{
public static void True([DoesNotReturnIf(false)] bool condition)
{
if (!condition)
{
throw new Exception("!!!");
}
}
}
然后:
public void TestMethod(object? o)
{
Ensure.True(o != null);
Console.WriteLine(o.ToString()); // No warning
}
此因为:
[DoesNotReturnIf(bool)]
:放在bool参数上。如果参数具有指定的布尔值,则调用后的代码将无法访问
[DoesNotReturnIf(bool)]
: Placed on a bool parameter. Code after the call is unreachable if the parameter has the specified bool value
您可以这样声明一个警卫方法:
Alternatively, you can declare a guard method like this:
public static class Ensure
{
public static void NotNull([NotNull] object? o)
{
if (o is null)
{
throw new Exception("!!!");
}
}
}
并像这样使用它:
public void TestMethod(object? o)
{
Ensure.NotNull(o);
Console.WriteLine(o.ToString()); // No warning
}
此因为:
[NotNull]
:对于输出(ref / out参数,返回值),即使输出也不为空如果类型允许。 对于输入(按值/输入参数),返回时已知传递的值不为空。
[NotNull]
: For outputs (ref/out parameters, return values), the output will not be null, even if the type allows it. For inputs (by-value/in parameters) the value passed is known not to be null when we return.
当然,真正的问题是为什么您要这样做。如果您不希望值
为空
,则将其声明为 object?
,而不是 object
-这就是拥有NRT的关键所在。
Of course, the real question is why you want to do this. If you don't expect value
to be null
, then declare it as object?
, rather than object
-- that's the point of having NRTs.
这篇关于可以将外部功能用作可空防护吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!