在 2020 年的最后一天,博客园发起了一个开源项目:基于 .NET 的博客引擎 fluss,我抽空把源码下载下来看了下,发现在属性的定义中,有很多地方都用到了 null!
,如下图所示:
这是什么用法呢?之前没有在项目中用过,所以得空就研究了一下。
以前,!
运算符用来表示 “否”,比如不等于 !=
。在 C# 8.0 以后,!
运算符有了一个新意义—— null
包容运算符,用来控制类型的可空性。要了解 null
包容运算符,首先就要了解可为 null 的引用类型。
可为 null 的引用类型
C# 8.0 引入了可为 null 的引用类型,与可空类型补充值类型的方式一样,它们以相同的方式补充引用类型。也就是说,通过将 ?
追加到某引用类型,可以将变量声明为可以为 null 的引用类型。 例如,string?
表示可以为 null
的 string
。使用这些新类型可以更清楚地表达代码设计的意图 —— 比如将某些变量声明为 必须始终具有值,而其他一些变量声明为 可以缺少值。
借助这个定义,我们在定义引用类型的变量或属性时,便有了两种选择:
- 假定引用不可以为
null
。 当变量定义为不可以为null
时,编译器会强制执行规则——确保在不检查它们是否为null
的前提下,取消引用这些变量是安全的:- 变量必须初始化为非
null
值。 - 变量永远不能赋值为
null
。
- 变量必须初始化为非
- 假定引用可以为
null
。 当变量定义为可以为null
时,编译器会强制执行不同的规则——确保您自己已正确检查null
引用:- 只有当编译器可以保证该值不为
null
时,才可以取消引用该变量。 - 这些变量可以用默认的
null
值进行初始化,也可以在其他代码中赋值为null
。
- 只有当编译器可以保证该值不为
与 C# 8.0 之前对引用变量的处理相比,这个新功能提供了显著的优势。在早期版本中,不能通过变量的声明来确定设计意图,编译器没有为引用类型提供针对 null
引用异常的安全性。
通过添加可为 null
的引用类型,您可以更清楚地声明您的意图。null
值是表示一个变量不引用值的正确方法,请不要使用此功能从代码中删除所有的 null
值。而是,应向编译器和阅读代码的其他开发人员声明您的意图。通过声明意图,编译器会在您编写与该意图不一致的代码时警告您。
是不是读起来有点绕?还是直接看示例比较容易理解些,请继续往下看。首先,我们来
启用可为 null 的引用类型
有三种方法可以启用可为 null 的引用类型。
在项目文件中启用
<