历史遗留问题
大家都知道在C# 8.0之前,如果我们不对引用类型进行赋值,默认是会赋值为null的。例如:
1 2 3 4 5 6 |
|
以上代码中的p的Name应该为null, 如果想使用它的属性Length我们不得不先判断其是否为null,如果某个地方我们忘记了做null检查就很可能引发异常。
null! 是什么意思
C# 8.0 默认所有引用类型不能默认赋值为null,先看这段代码
1 |
|
这段代码在C# 8.0之前是不会有警告的,当Name未赋值时,这段代码会抛出空引用异常。 而在C# 8.0中,这段代码编译器会给出一个可能为空的警告。
解决这个警告只需要再Name后面加!(null-forgiving operator 暂时称为容错运算符吧)
1 |
|
这样就会告诉编译器,这个变量我不会赋值为null的,你不用管了!
但是如果Name为null 运行时还是会炮空引用异常。个人猜测微软之所以这么做是为了减少开发人员的空引用出错概率吧!
那么null!又是什么鬼呢? 我们想把null赋值给属性以往会这么做:
1 |
|
这段代码会给出警告,不能将null赋值给不可为空的类型,只要给null加上!就能解决:
1 |
|
这样看上去有点奇怪, 告诉编译器null不会为null?
我们换个思路来理解,我们可以理解null就是代表空的指针的一个变量名:
1 2 |
|
如果当初微软把null设计为none呢。如果还是无法理解,那么就记住,如果想要将引用类型赋值为null,在C# 8.0中就需要在null后面加上!
毕竟语言是人家设计的,有的地方也确实没必要深究。