写点什么

在.NET 框架中使用 C# 8 和可空引用类型

  • 2019-11-16
  • 本文字数:1852 字

    阅读完需:约 6 分钟

在.NET框架中使用C# 8和可空引用类型

本文要点:

  • 改变 C#版本需要直接修改项目文件

  • 全局启用可空引用类型只能在新的项目格式中实现

  • 可根据需要,在文件或行的基础上更改可空性

  • 使用可空属性以避免不必要的空检查。

  • 针对较旧的平台时,可使用 Nullable 包


尽管在.NET 框架中,C# 8 的一部分将永远不会得到支持,但是,如果我们知道一些技巧的话,那么可以启用可空引用类型

启用 C# 8

第一步是确保我们使用的是 Visual Studio 2019 16.3 版或更高版本。


然后,我们需要为 C# 8 配置我们的项目。如果我们习惯使用 Visual Studio 的话,那么,我们可能期望能够简单地更改项目设置。不幸的是,那种方式已经无效了。



在新规则下,C#的默认版本由我们要面向的框架决定。只有.NET Core 3.0 和.NET Standard 2.1 可以用 C# 8 ,其他的都从 C# 7.3 版本开始。


我们可以通过编辑项目文件来覆盖它。打开项目的.csproj 文件,并在 PropertyGroup 中添加下面这行代码:


<LangVersion>8.0</LangVersion>
复制代码


如果我们使用现代项目格式的话,那么,在解决方案资源管理器(Solution Explorer)中双击该项目就可以将其打开。我们可以识别出这个格式,因为 XML 文件看起来是这样的:


<Project Sdk="Microsoft.NET.Sdk">
复制代码


如果我们使用遗留项目格式的话,那么,直接编辑它有点复杂。可以选择关闭 Visual Studio,使用 Notepad 或其他文本编辑器。或者,我们可以安装Visual Studio的Power Commands,它会添加一个“Edit Project File”命令。作为参考,XML 文件的根看起来类似这个:


<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
复制代码

启用可空引用类型:

接下来是启用可空引用类型功能。如果我们使用现代项目格式的话,那么,我们可以通过在语言版本的后面添加如下所示的代码行来全局化实现这一点:


<Nullable>enable</Nullable>
复制代码


如果我们使用遗留项目格式的话,那么,这样做就不起作用。我们不会得到错误提示,编译器只是忽略这个设置。因此,我们必须逐个文件地启用它。要做到这一点,必须在每个文件的顶部添加可空指令:


#nullable enable
复制代码


如果我们希望逐步启用该功能,那么,在现代项目中也可以这么做。

可空性属性

有各种各样的属性可用于微调空检查器的行为。为了解释该功能,可以考虑如下函数:


bool TryGet(int key, out Customer? customer)
复制代码


隐含的约定是,如果该函数返回 true,那么,customer 参数将不为空。反之,如果该函数返回 false,那么,customer 参数将为空。


但是,这不是签名的一部分,因此,如果我们要这样使用这个函数,那么,我们就总是需要在 customer 上进行一个无关的空检查。解决方法是,添加一个阐明行为的属性:


bool TryGet(int key, [NotNullWhen(true)] out Customer? customer)
复制代码


从编译器的角度来看,这意味着,如果返回 true,那么,customer 将永远不会是空值。如果返回的是 false,它没有说明会发生什么情况,但是,这仍然足以解决签名问题了。


在《尝试可空引用类型》这篇文章中,Phillip Carter 详细地描述了各种属性:


  • 条件化的后置条件:MaybeNotNullWhen(bool)、 NotNullWhen(bool)

  • 依赖是非为空:NotNullIfNotNull

  • 流:DoesNotReturn、DoesNotReturnIf(bool)

  • 后置条件:MaybeNull、NotNull

  • 前置条件:AllowNull、DisallowNull

旧项目中的可空性属性

为了实际使用这些属性,需要定义它们。如果我们在使用.NET Standard 2.1 或.NET Core 3.0 的话,那么,这些已经是现成的了。否则,我们将不得不创建它们,把它们作为我们项目的一部分。


处理这个问题的传统方式是创建一个新的.NET Core 3 项目,使用 F12 对所需的属性进行反向工程。然后,我们可以把它粘贴到我们的项目上,并添加缺少的细节,对于属性来说,这只需要几分钟时间。


一种更简单的方法是,简单地安装 Maunel Römer 的Nullable包。这将把 NullableAttributes.cs 文件复制到我们的项目中,其中包括所有必需的属性。这个包没有编译过的组件,只是一个源代码文件。


这两种方法都要确保所有的属性被标记成“内部”,而不是公共。这是为了避免与也可能向后移植属性的其他库发生冲突。


作者介绍


Johathan Allen 于 90 年代后期开始为一家医疗诊所开发 MIS 项目,逐步地将它们从 Access 和 Excel 提升到企业解决方案。在为金融行业编写了 5 年自动交易系统后,他成了多个项目的顾问,这些项目包括机器人仓库的 UI、癌症研究软件的中间层以及一家大型房地产保险公司的大数据需求。在业余时间,他热衷于对 16 世纪的武术进行研究及相关的写作。


原文链接:


Using C# 8 and Nullable Reference Types in .NET Framework


2019-11-16 08:007125

评论

发布
暂无评论
发现更多内容

技术管理知识写作系列

Melody

写作计划

领导力学习课-总结

李印

个人成长 管理

瞰见 | 刚刚,暴涨的 GitLab 给我们带来了怎样的开源思考?

OpenTEKr

狄安瞰源

《重学Java高并发》Sempahore的使用场景与常见误区

中间件兴趣圈

Java高并发 Sempahore

微博评论架构设计

天天向上

架构实战营

【架构实战营】模块五作业

liu🍊

数字人民币试点呈现“全面开花”

CECBC

中国的区块链技术该高压打击虚拟货币之下,中国的区块链技术该如何发展?

CECBC

阿里云徐立:面向容器和 Serverless Computing 的存储创新

阿里巴巴云原生

阿里云 Serverless 容器 云原生

记录

Melody

复盘最近遇到的几个问题

李印

编码习惯 经验总结

DevOps反模式

俞凡

DevOps

在线文本差集计算工具

入门小站

工具

为什么SOLID原则仍然是现代软件架构的基石

topsion

CleanCode SOLID

网络安全好就业吗?

喀拉峻

网络安全 安全 信息安全 渗透

Python Qt GUI设计:QDrag拖拽数据传输类(基础篇—18)

不脱发的程序猿

Python PyQt GUI设计 QDrag

linux比较两个目录的差异

入门小站

Linux

模块五作业

doublechun

「架构实战营」

微信 ClickHouse 实时数仓的最佳实践

腾讯云大数据

Clickhouse 云数据仓库

选手机的一点建议

李印

手机 生活随想

元宇宙对网络技术的挑战,什么样的网络才能承载元宇宙的野心?

CECBC

没有一个人喜欢被改变 ——阅读《高绩效教练》有感

研发管理Jojo

倾听 敏捷教练 引导和教练

[Pulsar] Batch Messge的基本原理

Zike Yang

Apache Pulsar 11月日更

phpstudy开启Apache服务显示80端口被占用

咿呀呀

PHPStudy

哈佛商业评论:面向未来的组织

石云升

读书笔记 11月日更

如何利用 “集群流控” 保障微服务的稳定性?

阿里巴巴云原生

阿里云 高可用 云原生 集群 AHAS

28 K8S之控制器基础

穿过生命散发芬芳

k8s 11月日更

入驻快讯|欢迎AfterShip正式入驻 InfoQ 写作平台!

InfoQ写作社区官方

入驻快讯

独家交付秘籍,你确定不点开看看?

阿里巴巴云原生

阿里云 云原生 应用交付平台 ADP

Flink 实践教程-入门(8): 简单 ETL 作业

腾讯云大数据

flink 流计算 Oceanus

如何设计业务高性能高可用计算架构

天天向上

架构实战营

在.NET框架中使用C# 8和可空引用类型_编程语言_Jonathan Allen_InfoQ精选文章