快速了解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更易维护.方 ...
随机推荐
- JavaScript事件:事件处理模型(冒泡、捕获)、取消冒泡、阻止默认事件
(一)事件处理模型---事件冒泡.捕获 (1)事件冒泡 24 <body> 25 <div class="warpper"> 26 <div clas ...
- ARM cache 工作方式
综述 现在的CPU的速度远远高于现代存储器的速度所以出现了cache.按和CPU距离分为L1级和L2级(SM)等.这里主要记录一下自己对cache的工作方式的学习理解. cache工作方式 cahe是 ...
- 微信小程序 TypeScript bug
微信小程序 TypeScript bug 执行自定义预览前预处理命令失败! internal/modules/cjs/loader.js:584 throw err; ^ Error: Cannot ...
- Android Studio & Flutter Plugins & Dart plugins
Android Studio & Flutter Plugins & Dart plugins https://flutter.dev/docs/get-started/editor? ...
- skills share & free videos
skills share & free videos 技术分享 & 免费视频 https://www.infoq.cn/video/list WebAssembly https://w ...
- 微信小程序 API
微信小程序 API https://developers.weixin.qq.com/miniprogram/dev/component/cover-view.html demo https://de ...
- dart 匹配基本map
var map_start = RegExp(r'^\s*\{\s*'); var map_end = RegExp(r'^\}\s*(,)?\s*'); var hasComma = true; M ...
- Windows 常用命令与快捷键
1.自选区截图Shift+win+s 2.全屏截图Prtsc 3.活动窗口截图Alt+Prtsc 4.新建文件夹Ctrl + Shift + N 5.返回上级目录Alt + 上方向键 6.后退到上一次 ...
- centos7下载和安装 通过xshell连接,有手就行,小白教程
下载步骤: https://mirrors.aliyun.com/centos/?spm=a2c6h.13651104.0.0.3c3712b2NaHUdY 点击下载或者复制链接到迅雷下载 下载好以后 ...
- 力扣1052. 爱生气的书店老板-C语言实现-中等难度
题目 传送门 文本 今天,书店老板有一家店打算试营业 customers.length 分钟.每分钟都有一些顾客(customers[i])会进入书店,所有这些顾客都会在那一分钟结束后离开. 在某些时 ...