NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

在.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:007080

评论

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

面试官:MySQL 中 varchar(n) 中 n 最大取值为多少?

架构师之道

MySQL 编程 计算机

2小时开发《点球射门游戏》,动画演示思路(上),代码已开源

非喵鱼

Java 开源 游戏 12 月 PK 榜 世界杯足球游戏

MYSQL-INNODB索引构成详解

京东科技开发者

MySQL innodb 索引 B+树 InnoDB存储引擎

极客时间运维进阶训练营第七周作业

9527

Git实战(五)| 让工作更高效,搞定Git的分支管理

霍格沃兹测试开发学社

手把手教你构建数据安全体系,守住安全合规红线

王巍

数据安全

前端面试题(附答案)

loveX001

JavaScript

基于阿里云IoT平台OTA进行APP确认升级的方案——业务架构类

阿里云AIoT

物联网 UED 数据格式

ReactDOM.render在react源码中执行之后发生了什么?

flyzz177

React

潦草手写体也能轻松识别,快速提取文字不用愁

HMS Core

HMS Core

ZBC登录iZUMi Finance双挖池APY高达189%,极致通缩的典范

西柚子

React Context源码是怎么实现的呢

flyzz177

React

跨机房ES同步实战

京东科技开发者

迁移 迁移数据 异步多活 Elastic Search 数据库·

百度 Android 直播秒开体验优化

百度Geek说

android 百度app 12 月 PK 榜 直播优化

前端工程师leetcode算法面试必备-二分搜索算法(上)

js2030code

JavaScript LeetCode

Git实战(四)| Git分支管理实操,搞定在线合并和本地合并

霍格沃兹测试开发学社

深入理解JS作用域链与执行上下文

loveX001

JavaScript

前端面试指南之JS面试题总结

loveX001

JavaScript

区块链“入局”证券市场,未来前景有多大?

旺链科技

区块链 产业区块链 证券行业 12 月 PK 榜

KAFKA EAGLE 监控MRS kafka之操作实践

华为云开发者联盟

开发 华为云 12 月 PK 榜

用javascript分类刷leetcode3.动态规划(图文视频讲解)

js2030code

JavaScript LeetCode

前端刷完这12道滑动窗口,就可以出山面试了

js2030code

JavaScript LeetCode

损失高达3亿美元|如何保护源代码安全?

SEAL安全

12 月 PK 榜 源代码安全 最小权限管理 零信任模型

IoT高级设备检索——设备管理运维类

阿里云AIoT

数据库 监控 物联网 传感器 Cloud Native

做了一份前端面试复习计划,保熟~

loveX001

JavaScript

算法 KECP 被顶会 EMNLP 收录,极少训练数据就能实现机器阅读理解

阿里云大数据AI技术

自然语言处理 机器学习 12 月 PK 榜 机器阅读

2 小时开发《点球射门游戏》,动画演示思路(下),代码已开源

非喵鱼

Java 开源 游戏 12 月 PK 榜 世界杯足球游戏

借用FinClip把小程序游戏运行到自有App中

Onegun

小游戏 小游戏开发 微信小游戏

Idea居然还有比Navicat、Datagrid工具还好用、还快的插件,效率又可提升一倍了

非喵鱼

Java MySQL redis IDEA 12 月 PK 榜

掌握 CORS 跨域请求,读这一篇文章就够了

范家鹏

HTTP CORS 跨域 异步请求 跨域资源共享

软件测试 | 版本控制神器GitHub的基本使用与踩坑

测试人

GitHub 软件测试 自动化测试 测试开发

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