C# 8.0 的可空引用类型,不止是加个问号哦!你还有很多种不同的可空玩法

本文主要是介绍C# 8.0 的可空引用类型,不止是加个问号哦!你还有很多种不同的可空玩法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

C# 8.0 引入了可空引用类型,你可以通过 ? 为字段、属性、方法参数、返回值等添加是否可为 null 的特性。

但是如果你真的在把你原有的旧项目迁移到可空类型的时候,你就会发现情况远比你想象当中复杂,因为你写的代码可能只在部分情况下可空,部分情况下不可空;或者传入空时才可为空,传入非空时则不可为空。


本文内容

    • C# 8.0 可空特性
    • 更灵活控制的可空特性
      • 输入:`AllowNull`
      • 输入:`DisallowNull`
      • 输出:`MaybeNull`
      • 输出:`NotNull`
      • `NotNullWhen`, `MaybeNullWhen`
      • `NotNullIfNotNull`
    • 在早期 .NET Framework 或者早期版本的 .NET Core 中使用
    • Walterlv.NullableAttributes

C# 8.0 可空特性

在开始迁移你的项目之前,你可能需要了解如何开启项目的可空类型支持:

  • C# 8.0 如何在项目中开启可空引用类型的支持 - walterlv

可空引用类型是 C# 8.0 带来的新特性。

你可能会好奇,C# 语言的可空特性为什么在编译成类库之后,依然可以被引用它的程序集识别。也许你可以理解为有什么特性 Attribute 标记了字段、属性、方法参数、返回值的可空特性,于是可空特性就被编译到程序集中了。

确实,可空特性是通过 NullableAttributeNullableContextAttribute 这两个特性标记的。

但你是否好奇,即使在古老的 .NET Framework 4.5 或者 .NET Standard 2.0 中开发的时候,你也可以编译出支持可空信息的程序集出来。这些古老的框架中没有这些新出来的类型,为什么也可以携带类型的可空特性呢?

实际上反编译一下编译出来的程序集就能立刻看到结果了。

看下图,在早期版本的 .NET 框架中,可空特性实际上是被编译到程序集里面,作为 internalAttribute 类型了。
反编译

所以,放心使用可空类型吧!旧版本的框架也是可以用的。

更灵活控制的可空特性

阻碍你将老项目迁移到可空类型的原因,可能还有你原来代码逻辑的问题。因为有些情况下你无法完完全全将类型迁移到可空。

例如:

  1. 有些时候你不得不为非空的类型赋值为 null 或者获取可空类型时你能确保此时一定不为 null(待会儿我会解释到底是什么情况);
  2. 一个方法,可能这种情况下返回的是 null 那种情况下返回的是非 null
  3. 可能调用者传入 null 的时候才返回 null,传入非 null 的时候返回非 null

为了解决这些情况,C# 8.0 还同时引入了下面这些 Attribute

  • AllowNull: 标记一个不可空的输入实际上是可以传入 null 的。
  • DisallowNull: 标记一个可空的输入实际上不应该传入 null。
  • MaybeNull: 标记一个非空的返回值实际上可能会返回 null,返回值包括输出参数。
  • NotNull: 标记一个可空的返回值实际上是不可能为 null 的。
  • MaybeNullWhen: 当返回指定的 true/false 时某个

这篇关于C# 8.0 的可空引用类型,不止是加个问号哦!你还有很多种不同的可空玩法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/513735

相关文章

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

一文解析C#中的StringSplitOptions枚举

《一文解析C#中的StringSplitOptions枚举》StringSplitOptions是C#中的一个枚举类型,用于控制string.Split()方法分割字符串时的行为,核心作用是处理分割后... 目录C#的StringSplitOptions枚举1.StringSplitOptions枚举的常用

Python内存管理机制之垃圾回收与引用计数操作全过程

《Python内存管理机制之垃圾回收与引用计数操作全过程》SQLAlchemy是Python中最流行的ORM(对象关系映射)框架之一,它提供了高效且灵活的数据库操作方式,本文将介绍如何使用SQLAlc... 目录安装核心概念连接数据库定义数据模型创建数据库表基本CRUD操作创建数据读取数据更新数据删除数据查

C#自动化实现检测并删除PDF文件中的空白页面

《C#自动化实现检测并删除PDF文件中的空白页面》PDF文档在日常工作和生活中扮演着重要的角色,本文将深入探讨如何使用C#编程语言,结合强大的PDF处理库,自动化地检测并删除PDF文件中的空白页面,感... 目录理解PDF空白页的定义与挑战引入Spire.PDF for .NET库核心实现:检测并删除空白页

C#利用Free Spire.XLS for .NET复制Excel工作表

《C#利用FreeSpire.XLSfor.NET复制Excel工作表》在日常的.NET开发中,我们经常需要操作Excel文件,本文将详细介绍C#如何使用FreeSpire.XLSfor.NET... 目录1. 环境准备2. 核心功能3. android示例代码3.1 在同一工作簿内复制工作表3.2 在不同

C#中通过Response.Headers设置自定义参数的代码示例

《C#中通过Response.Headers设置自定义参数的代码示例》:本文主要介绍C#中通过Response.Headers设置自定义响应头的方法,涵盖基础添加、安全校验、生产实践及调试技巧,强... 目录一、基础设置方法1. 直接添加自定义头2. 批量设置模式二、高级配置技巧1. 安全校验机制2. 类型

C#使用iText获取PDF的trailer数据的代码示例

《C#使用iText获取PDF的trailer数据的代码示例》开发程序debug的时候,看到了PDF有个trailer数据,挺有意思,于是考虑用代码把它读出来,那么就用到我们常用的iText框架了,所... 目录引言iText 核心概念C# 代码示例步骤 1: 确保已安装 iText步骤 2: C# 代码程

C#实现高性能拍照与水印添加功能完整方案

《C#实现高性能拍照与水印添加功能完整方案》在工业检测、质量追溯等应用场景中,经常需要对产品进行拍照并添加相关信息水印,本文将详细介绍如何使用C#实现一个高性能的拍照和水印添加功能,包含完整的代码实现... 目录1. 概述2. 功能架构设计3. 核心代码实现python3.1 主拍照方法3.2 安全HBIT

C#实现SHP文件读取与地图显示的完整教程

《C#实现SHP文件读取与地图显示的完整教程》在地理信息系统(GIS)开发中,SHP文件是一种常见的矢量数据格式,本文将详细介绍如何使用C#读取SHP文件并实现地图显示功能,包括坐标转换、图形渲染、平... 目录概述功能特点核心代码解析1. 文件读取与初始化2. 坐标转换3. 图形绘制4. 地图交互功能缩放

C#使用SendMessage实现进程间通信的示例代码

《C#使用SendMessage实现进程间通信的示例代码》在软件开发中,进程间通信(IPC)是关键技术之一,C#通过调用WindowsAPI的SendMessage函数实现这一功能,本文将通过实例介绍... 目录第一章:SendMessage的底层原理揭秘第二章:构建跨进程通信桥梁2.1 定义通信协议2.2