Nullable Reference Types为什么会出现在C#之中?

  Nullable Reference Types(NRT),是在C# 8(.net core3.1)引入C#的一个重要的功能,并且在C#10(.NET6)中默认开启。

    在代码中最直观的改动就是引入了“?”, 你可以使用string?, int?等等来代表一个类型可为空。当然对于值类型来说,?其实是Nullable<T>的语法糖,比如int?本质的类型就是Nullable<int>。这时候 int? a = null;的操作也是可以成立的

    可能一开始很多人都没有理解这个功能的本质,只会觉得,怎么我的项目一到.NET6突然多了一堆波浪号警告,或是认为这个类型好像只对一些值类型管用,毕竟引用类型本来就是可以为null嘛,加个?有什么用,还麻烦。

    这么理解其实也不算完全错误。是的,NRT为值类型引入了可空的值,这是一项最容易被理解的功能,当然也是非常实用的功能之一。不过这并不是NRT真正面对的敌人

图片

    NRT真正想要解决的是null这个恶魔会引发的灾难,NullReferenceException(NRE)

    NRE一直都是许多编程者们的噩梦,稍有不注意,他就会隐藏在代码之中。成为一颗随时会爆炸的地雷。现在也有非常多的人认为,Null本身就不该存在在语言之中,他就是一个纯粹的恶魔,毒药。

    C#作为一个老牌,稳定(也许不那么稳定(笑))了许久的语言,自然已经没有选择"大刀阔斧的直接砍掉null"的余地,他引入了NRT这个功能。


    我们需要了解的是,启用NRT有一个深层含义,其意味着一个语义的反转。这也是造成当项目启用NRT之后,往往能看到漫天报警的原因。

    引用类型默认为可空 -> 需要显式标记引用类型可为空

    这也许会觉得看起来没什么,但事实上意义重大。代码现在能以显式的方式告诉编程者,或是编译器,这个类型可不可为空。

事实上启用了#nullable(NRT)并不会影响引用类型设置为null(即使没有任何标记,你还是可以将他设置为null),这其实有点语义上的错位,启用了NRT后事实上反而是不允许未标记可为空的类型,设置为null。

    经过了上述的改动后。现在我们再来看我们的代码。我们已经明确的知晓了,我们代码中哪些参数,变量可为空。而不像以前一样,所有引用类型都为空。

    在拥有NRT之前,我们必须要手动的校验所有引用类型的参数或是变量,才可以确保不会被恶魔NRE,以未知的方式在代码中抛出错误。而现在,我们把这个隐患暴露在了阳光之下,引用类型应当默认不可为空(从此处出发,读者可以想想,变量是否也应该"不变"? ),所有可空类型,必须要向我们报告,他是可空的。
这样有两个好处,其一是我们可以不必再对所有的引用类型去做判空处理,当然,这个还不够。因为事实上还是可以传入null。其二则是编译器可以代替我们检查,哪里的代码,有被NRE恶魔侵扰的隐患。所以漫天的报警(当然这些报警的行为也是在不断优化的,现在会好不少),其实都是一些大大小小的隐患,应该要去正确的声明他,或是让他拥有该有的值。 

配合??=运算符(当变量为空则等于),以及damnit运算符(!,用来显示告诉编译器该变量不为空,常用于编译器无法推断,或是手动测试null的情况时使用)可以更好的使用NRT功能。

测试代码如下,可以放到ide中看看有什么报警吧~


// See https://aka.ms/new-console-tesmplate for more information

string a = null;

string? c = String.Empty;

c = a;
Test("");
Test(c);
Test(a);
Test(null);
Test(null!);

return;

void Test(string b)
{
    Console.WriteLine(b);
}

void Test1(string? b)
{
    
    Console.WriteLine(b.Length);
    b ??= string.Empty;
    Console.WriteLine(b.Length);
}

视频链接: Nullable Reference Types(NRT)为什么会出现在C#之中?_哔哩哔哩_bilibili

公众号搜索:scixing的炼丹房

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值