.NET 6学习笔记(4)——解决VS2022中Nullable警告
很多小伙伴在升级到Visual Studio 2022后发现,如果我们去新建一个.NET 6的项目,和原先VS2019中一摸一样的写法,却会出现CS8618 Non-nullable property或者其他可能为null的警告。虽然不影响代码的编译和运行,却让人心里不踏实。
这是因为VS2019除了.NET Core 3.x的项目类型,都是默认使用C# 7.3版本。而从C# 8.0之后,增加了对可为null类型的检查,旨在最大程度的减少运行时出现NullReference异常。
除非小伙伴们时刻关心C#版本更新内容,否则这个随着VS2022和.NET 6默认开启的新特性,可能带来的不是惊喜,反而有一点惊吓。
那么让我们来看看如何迎接这个新的改变。这个变化的主旨是希望代码中,尽可能不再有为null的情况。首先我们来看最常见的一个Warning,在属性声明的时候。

平平无奇的写法,其中却蕴藏着两个Warnings。这种的处理较为简单,给出明确的初始值即可。例如string.Empty。你可以觉得这是在脱裤子放屁,但是回过头想一想,在运行过程中FristName和LastName为“”的情况,一定是代码有意为之。而不是不知道哪里返回了一个null,且无意中赋值上去了。

第二种常见的情况,是我们获得了一个可为null类型的对象,然后直接使用了。下图中XDocument的Load方法返回了Xelement?类型的对象。如果我们不做null check,就会存在Warning的波浪线。

一般来说这里加个if判断,就完事了。至少这个方法本身算是交差了。就像Xdocument.Root这个属性一样。但是业务代码的设计,和基础框架API的设计在思路上是有区别的。业务代码在业务明确的情况下返回null,会造成一种无限套娃的微妙效果。就像下面这个,到了外面一层的使用方法,仍然要纠结于null check。

从这个方法看,如果我就是一定要获取Root对象,或者对Root对象做一些不可描述的事情。那么XML文件中root节点为空就是一个不可接受,完全错误的情况。我个人倾向直接throw NullReferenceException。

另一种相似的情况是,可空类型被作为参数在接下来的代码中使用。下面代码中的attribute在业务逻辑中,很有可能就不应该存在为null的情况。否则就是输入的源头有错误。

这时要么通过if来回避参数为null这个错误,要么干脆就把错误暴露出来。这里推荐使用ArgumentNullException的静态方法ThrowIfNull。比先写个if判断再throw的方式要省力得多。

Visual Studio通过代码静态分析来判断是否报告可为null的Warning。但是代码写起来是非常灵活的,所以有时候会有误报或者分析不出来的情况。比如下面这个例子。

明明已经对相同的对象做了null check,但仍然会有Warning,这是因为Visual Studio并不认为这两段重复的代码是同一个东西。处理的方式也很简单,一是老老实实通过建立局部变量的引用来避免重复。

二是通过惊叹号(!)操作符告诉Visual Studio,我确信这里没有问题,别逼逼了。所以可以有下面这个写法。当然我个人并不推荐这么做,首先是这个写法不兼容之前低版本的C#,万一要做一个向低版本的移植或兼容就麻烦了。其次!操作符有些过度自信的感觉,它没有实际的意义,仅仅是关闭了这个Warning,颇有掩耳盗铃的意思。

以上就是今天想和大家讨论的,关于迁移到Visual Studio 2022和C# 10以后,遇到的可为null类型的问题。持续性的学习不是说要每个小版本都紧跟潮流,而是在每一次的新项目,新团队,新机遇到来的时候,即时地更新自己。一点浅见,抛砖引玉。
以下链接,是MS Learn上Windows开发的入门课程,单个课程三十分钟到60分钟不等,想要补充基础知识的同学点这里:
开始使用 Visual Studio 开发 Windows 10 应用
.NET 6学习笔记(4)——解决VS2022中Nullable警告的更多相关文章
- 【整理】解决vue不相关组件之间的数据传递----vuex的学习笔记,解决报错this.$store.commit is not a function
解决vue不相关组件之间的数据传递----vuex的学习笔记,解决报错this.$store.commit is not a function https://www.cnblogs.com/jaso ...
- Android(java)学习笔记167:Java中操作文件的类介绍(File + IO流)
1.File类:对硬盘上的文件和目录进行操作的类. File类是文件和目录路径名抽象表现形式 构造函数: 1) File(String pathname) Creat ...
- [C#] 类型学习笔记一:CLR中的类型,装箱和拆箱
在学习.NET的时候,因为一些疑问,让我打算把.NET的类型篇做一个总结.总结以三篇博文的形式呈现. 这篇博文,作为三篇博文的第一篇,主要探讨了.NET Framework中的基本类型,以及这些类型一 ...
- [原创]java WEB学习笔记39:EL中的运算符号(算术运算符,关系运算符,逻辑运算符,empty运算符,条件运算符,括号运算符)
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- [原创]java WEB学习笔记38:EL 中的 11个 隐含对象 详解
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- [原创]java WEB学习笔记05:Servlet中的ServletConfig对象
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- Android(java)学习笔记110:Java中操作文件的类介绍(File + IO流)
1.File类:对硬盘上的文件和目录进行操作的类. File类是文件和目录路径名抽象表现形式 构造函数: 1) File(String pathname) Creat ...
- Python学习笔记之从文件中读取数据
10-1 Python 学习笔记:在文本编辑器中新建一个文件,写几句话来总结一下你至此学到的Python 知识,其中每一行都以“In Python you can”打头.将这个文件命名为learnin ...
- Docker学习笔记之-在CentOS中安装Docker
上一节演示了如何 通过Xshell连接CentOS服务,链接:Docker学习笔记之-通过Xshell连接 CentOS服务 本节将演示 如何在CentOS中安装 Docker 第一步:更新系统包到最 ...
随机推荐
- Thymeleaf 公共css,js提取及自有css,js导入
https://www.jianshu.com/p/2102fa4772ba
- ES6 - promise(1)
今天决定对之前学过的一些前端的知识进行梳理和总结,因为最近都是独自承担项目的开发与搭建,所以先从前后端交互的第一线axios来梳理,复习axios首先一定要先复习promise对象. 什么是promi ...
- 接口测试postman深度挖掘应用③--postman终结篇
上一章节我们介绍了postman的变量测试以及导入数据测试基本上技术性的东西已经差不过了,这篇文章再系统性的介绍一下. 一.下载 官网:https://www.postman.com 1.选择需要下载 ...
- 【Java面试】什么是可重入,什么是可重入锁? 它用来解决什么问题?
一个工作了3年的粉丝,去一个互联网公司面试,结果被面试官怼了. 面试官说:"这么简单的问题你都不知道? 没法聊了,回去等通知吧". 这个问题是: "什么是可重入锁,以及它 ...
- 大功率超远距离lora无线数传电台,多级中继功能
一.在无线通信领域,LoRa是目前市场最被看好的技术之一.随着新一代LoRa调制技术的升级,市场对LoRa技术的认知.认可逐步提高,基于LoRa调制技术开发的产品得到更广泛的应用.受益于其超低的接收灵 ...
- tmux(Terminal MultipleXer)命令使用
作用:命令行多窗口显示:命令行程序与本机脱离 1 安装tmux (1)redhat.centos系统 yum install tmux (2)ubuntu系统 apt-get install tmux ...
- 开启网易邮箱客户端授权码-POP/SMTP/IMAP
打开网易邮箱首页 https://mail.163.com/ 登录邮箱. 点击上方设置,选择POP/SMTP/IMAP选项. 选择开启对应的协议,IMAP或者POP3分别为不同的收信协议 在新弹出的弹 ...
- Android 12(S) 图像显示系统 - HWC HAL 初始化与调用流程
必读: Android 12(S) 图像显示系统 - 开篇 接口定义 源码位置:/hardware/interfaces/graphics/composer/ 在源码目录下可以看到4个版本的HIDL ...
- 使用navicat连接远程linux mysql数据库出现10061
重启mysql服务 两种方式 1.使用 service 启动:service mysql restart 2.使用 mysqld 脚本启动:/etc/inint.d/mysql restart
- .NET ORM框架HiSql实战-第二章-使用Hisql实现菜单管理(增删改查)
一.引言 上一篇.NET ORM框架HiSql实战-第一章-集成HiSql 已经完成了Hisql的引入,本节就把 项目中的菜单管理改成hisql的方式实现. 菜单管理界面如图: 二.修改增删改查相关代 ...