快速了解C# 8.0中“可空引用类型(Nullable reference type)”语言特性
Visual C# 8.0中引入了可空引用类型(Nullable reference type),通过编译器提供的强大功能,帮助开发人员尽可能地规避由空引用带来的代码问题。这里我大致介绍一下可空引用类型的基本内容。
刚开始接触这个语言特性的时候,可能会不太容易理解。引用类型本来不就是可以为空(null)的么,为啥还要特别地引入“可空引用类型”的概念呢?其实这是从编译器的角度要求开发人员在编程的时候就考虑某个变量是否有可能为空,从而尽可能地减少由空引用所带来的代码错误。
假设有如下类:
class Student
{
public Student(string name, DateTime dayOfBirth)
=> (Name, DayOfBirth) = (name, dayOfBirth);
public string Name { get; set; }
public DateTime DayOfBirth { get; set; }
public string Notes { get; set; }
}
此类定义了一个“学生”实体的基本信息,为了简化起见,这里只列出了需要讨论的几个属性:
- Name:学生姓名
- DayOfBirth:学生生日
- Notes:对学生信息的一些备注
假设我们有两个操作:在所有学生中,找出所有具有备注信息的学生,以及对所有学生按姓名排序,在C#中很容易使用Linq来实现:
var studentsHasNotes = students.Where(s => s.Notes.Length > 0);
以及:
var orderedStudents = students.OrderBy(s => s.Name);
到目前为止没啥问题,程序能够正常运行。然而仔细进行代码审查不难发现,在获取所有具有备注信息的学生的代码中(也就是上面第一段代码中),有可能出现空引用的异常,因为对于一个“学生”实体来说,它的Notes属性是有可能为null的。
现在我们打开“可空引用类型”这一语言特性,打开方式主要有两种:可以在项目级别,编辑csproj项目文件进行设置,也可以通过#nullable预编译指令来实现:
- 编辑csproj项目文件,加入
<Nullable>enable</Nullable>即可:

- 通过#nullable预编译指令来实现,只需要在代码中需要的地方加入#nullable指令即可:

启用“可空引用类型”这一语言特性之后你会发现,在上面的Student类的构造函数处出现了一个警告,提示在构造函数执行完成时,不可为空的“Notes”属性需要有一个不为空的值,建议将其设置为可空的string类型。为什么编译器仅提示Notes有可能为空,而不是Name属性呢?因为构造函数中已经为Name赋值了,因此,对于任何一个Student的对象,Name不可能为空,而Notes则不然。

Name不可能为空?它不是string类型么?万一在代码中它为空了怎么办?别急,编译器是不会允许出现这种情况的:

在此,我们将Notes属性设置为string?类型,于是你会发现,位于构造函数上的警告信息已经没有了,因为我们允许Student对象可以没有Notes数据,但在“找出所有具有备注信息的学生”这一操作时,又会出现警告,提示说Notes有可能为空:

于是,你会发现,在启用了可空引用类型的语言特性后,我们就需要仔细考察Student类型中的每一个引用类型的属性,看它在实际应用中是否有可能为空,如果可能为空,则用可空引用类型来定义属性,之后编译器就会帮助你来分析哪些地方有可能存在空引用。
在上面的“找出所有具有备注信息的学生”例子中,如果你觉得Notes肯定不会为空,那么也可以使用“!”操作符来覆盖编译器的警告信息,比如:

现在流行的.NET开源框架基本上都已经支持了可空引用类型了,而且如果你是一名开源框架的开发人员,也强烈建议在你的框架中启用这一语言特性来尽可能地避免空引用问题。比如,如果你在代码中启用了可空引用类型特性,那么当你从Newtonsoft.Json的JsonConverter类继承时,你会发现,你必须使用可空引用类型的函数重载:

但如果你没有启用可空引用类型特性,那么当你从Newtonsoft.Json的JsonConverter类继承时,你会发现,重载函数的签名与以前一样:

好了,对于C# 8.0的“可空引用类型”大致就介绍这么多,相信应该已经基本上概括了它的要点和使用方式,在日常开发中应该够用了。
快速了解C# 8.0中“可空引用类型(Nullable reference type)”语言特性的更多相关文章
- [译]C#8.0中一个使接口更加灵活的新特性-默认接口实现
9月份的时候,微软宣布正式发布C#8.0,作为.NET Core 3.0发行版的一部分.C#8.0的新特性之一就是默认接口实现.在本文中,我们将一起来聊聊默认接口实现. 众所周知,对现有应用程序的接口 ...
- C#中的值类型(value type)与引用类型(reference type)的区别
ylbtech- .NET-Basic:C#中的值类型与引用类型的区别 C#中的值类型(value type)与引用类型(reference type)的区别 1.A,相关概念返回顶部 C#中 ...
- 【Unity3D】中的空引用 Null Reference Exception
Null Reference Exception : Object reference not set to an instance of an object. 异常:空引用,对象的引用未设置到对象的 ...
- Nullable Reference Types 可空引用类型
在写C#代码的时候,你可能经常会遇到这个错误: 但如果想避免NullReferenceException的发生,确实需要做很多麻烦的工作. 可空引用类型 Null Reference Type 所以, ...
- C# 8 - Nullable Reference Types 可空引用类型
在写C#代码的时候,你可能经常会遇到这个错误: 但如果想避免NullReferenceException的发生,确实需要做很多麻烦的工作. 可空引用类型 Null Reference Type 所以, ...
- 迫不及待地体验了一把 C#8.0 中的可空引用类型(Nullable Reference)
在我之前的一篇博客 NullReferenceException,就不应该存在! 中,我吐槽了 C# 中 null 的弊端以及避免 null 的方法:事实上这本都是现代高级语言中极力推崇的做法.Kot ...
- C#8.0可空引用类型的使用注意要点
最近VS2019正式版发布了,装下来顺便试用了一下C#8.0,最大的看点应该就是可空引用类型了.不过C#8.0仍然处于Beta的状态,而且试用时也遇到了几个坑. 背景知识说明: 所谓的可空引用类型是指 ...
- C#3.0中的扩展方法
在实际应用中,开发者完成代码的编译后,除非重新编译更改后的代码,否则开发者很难在原有代码中添加新的功能. 在C#3.0中,提供了一个扩展方法的新特性,可以使得开发者在编译后的程序集里边添加相关的方法, ...
- vue2.0中使用less
第一部分:Less语言 与上一篇<vue2.0中使用sass>介绍的Sass语言一样,Less语言也是一种CSS的扩展语言,增加了变量.混合(minin).函数等功能,让CSS更易维护.方 ...
随机推荐
- 009.NET5_程序的发布运行
发布 相差了web.config文件 脚本启动 cmd,进入程序根目录. 带参启动 其实,最终与web.config中效果一样
- 如何从 ToB 企业级 IM 产品中学习技术选型和架构
如何从 ToB 企业级 IM 产品中学习技术选型和架构 多端,全端 React React Native Flutter Electron Lark https://www.larksuite.com ...
- 如何使用 js 检测控制台被用户打开了
如何使用 js 检测控制台被用户打开了 js solutions 监听 F12 事件 监听键盘快捷键组合 Ctrl + Shift + I Option + Command + I Object.to ...
- VirtualBox All in One
VirtualBox All in One 虚拟机 / VM / Virtual Machine x86 and AMD64/Intel64 VirtualBox is a powerful x86 ...
- WebAssembly All In One
WebAssembly All In One wasm https://webassembly.org/ https://developer.mozilla.org/en-US/docs/WebAss ...
- VSCode & SQL
VSCode & SQL MySQL MySQL https://marketplace.visualstudio.com/items?itemName=formulahendry.vscod ...
- CSS Learning Paths
CSS Learning Paths CSS Expert refs https://developer.mozilla.org/en-US/docs/Web/CSS https://css-tric ...
- 离场定高转弯DF与CF的对比
也许是刚学会CAD的缘故,配合风螺旋插件,画图的感觉真是蛮爽的,忍不住画了一张又一张. 接着昨天的离场保护区,我们来聊一下PBN指定高度转弯保护区的画法.指定高度转弯的计算本身没有太多复杂的地方,真正 ...
- alpakka-kafka(2)-consumer
alpakka-kafka-consumer的功能描述很简单:向kafka订阅某些topic然后把读到的消息传给akka-streams做业务处理.在kafka-consumer的实现细节上,为了达到 ...
- eclipse安装mybatis的插件
在help中打开Eclipse Marketplace... 输入mybatis后搜索,点击install即可 功能说明: 1.查找某一个方法 在dao接口中 按住Ctrl键,鼠标指到方法名称上 选择 ...