C#8引入了可为空的引用类型,这是一个非常酷的功能。现在,如果您希望获取可为空的值,则必须编写所谓的警卫:
object? value = null;
if (value is null)
{
throw new ArgumentNullException();
}
…
这些可能是重复的。我想知道的是,是否有可能避免为每个变量编写这种类型的代码,而是有一个防护类型的static void
函数,如果value为null
则引发异常,或者如果value不是null
则仅返回。还是这太难了,编译器无法推断?特别是如果它是外部库/包?
c#大神给出的解决方案
您可以做几件事。
您可以在guard方法中使用[DoesNotReturnIf(...)]
,以指示在特定条件为true或false时引发的错误,例如:
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
}
works because:
[DoesNotReturnIf(bool)]
:放置在布尔参数上。如果参数具有指定的布尔值,则调用后的代码将无法访问
另外,您可以这样声明一个警卫方法:
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
}
works because:
[NotNull]
:对于输出(ref / out参数,返回值),即使类型允许,输出也不会为null。对于输入(按值/输入参数),已知返回时传递的值不为null。
SharpLab with examples
当然,真正的问题是为什么要这样做。如果您不希望value
是null
,则将其声明为object?
,而不是object
-这就是拥有NRT的关键所在。
java.net.URI.create("http://adserver.adtech.de/adlink|3.0") 抛出java.net.URISyntaxException: Illegal character in path at index 32: http://adserver.adtech.de/adlink|3.0 虽然n…
LeetCode题解计算机为什么是基于二进制的?可以是三进制么?二进制有什么好处?题解:为什么叫电子计算机?算盘应该没有二进制
LeetCode题解黑白圆盘一个圆盘被涂上了黑白二色,两种颜色各占一个半圆。圆盘以一个未知的速度、按一个未知的方向旋转。你有一种特殊的相机可以让你即时观察到圆上的一个点的颜色。你需要多少个相机才能确定圆盘旋转的方向?题解:可以用一个相机即可
LeetCode题解圆上任取三点构成锐角三角形的概率来自字节跳动的一道几何题题解:1/4
LeetCode题解深度优先遍历和回溯的关系?深度优先遍历的范围更大还是回溯的范围更大?为什么?题解:我的理解是:dfs是回溯思想的一种体现- 回溯:是在整个搜索空间中搜索出可行解,在搜索过程中不断剪枝回退,这是回溯的思想,这个搜索空间并没有限制于特定的数据结构。- dfs:dfs是指特定的数据结构中如图,树(特殊的图)中搜索答案,范围限制在了特定的数据结构。个人拙见。