可以将外部功能用作可空防护吗? - c#

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

当然,真正的问题是为什么要这样做。如果您不希望valuenull,则将其声明为object?,而不是object-这就是拥有NRT的关键所在。

java.net.URI.create异常 - java

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是指特定的数据结构中如图,树(特殊的图)中搜索答案,范围限制在了特定的数据结构。个人拙见。