C# 11 中的 required members

C# 11 中的 required members

Intro

在 C# 11 中引入了一个新的特性 —— Required Members,引入了一个新的 required 关键词,可以用来表示字段或者属性在类型初始化的时候必须要进行初始化,这一特性也进一步的改进了可空引用类型的用法。

Sample

示例如下:

private record Person
{public required string FirstName { get; init; }public required string LastName { get; init; }public int Age { get; set; }public string? Description { get; set; }
}

在现在的 C# 中,如果没有 required 启用了可空引用类型, FirstNameLastName 就会有下面这样的编译器警告

ad71f1d1e07e13d68b447499c8ecb0ef.png

目前的做法基本上是声明一个默认值比如:

public string FirstName { get; init; } = string.Empty;
public string FirstName { get; init; } = null!;

有了 required 修饰符后,就不需要再这样写了也不会有警告了

102eca5115442353b65509c0f4a477c1.png


声明为 required 之后在对象初始化的时候就必须要进行赋值如果不赋值编译器就会报错

2bf08950cbf1d063375c77e2c173546a.png

required members not inited error

对所有的 required 成员进行初始化之后就不会再报错了

9678960aa427a0175ead16080b20f1ec.png

那么它只能用于启用了可空引用类型的不可为空的引用类型吗,并不是的,对于值类型和可以为空的引用类型也是可以使用的,required 只表示成员需要进行初始化,对于可空引用类型的分析做了一些优化

例如:

private record Person
{public required string FirstName { get; init; }public required string LastName { get; init; }public int Age { get; set; }public required string? Description { get; set; }
}private sealed class Pet
{public required string Name { get; init; }public required int Age { get; init; }
}

你也可以使用继承来扩展

private record Person
{public required string FirstName { get; init; }public required string LastName { get; init; }public int Age { get; set; }public string? Description { get; set; }
}private sealed record Student : Person
{public required int Id { get; set; }
}

这样我们初始化的时候 Student 类型中的 Id 和继承于 Person 的 required 成员都需要进行初始化

5dcc22a7b945b278b9cf33266353a0ed.png

如果我们类型中有特殊的构造方法,我们在构造方法上对这些 required 成员进行了初始化,那么我们就不需要再初始化这些 required 成员了但是目前编译器还没做到这一点,目前需要我们手动的在初始化了 required 成员的构造方法上添加一个 SetsRequiredMembers atrribute,以告知编译我们在这个构造方法中已经初始化了 required 成员,不要再报告错误了,这一点感觉也是现在体验一个不太好的一个地方

private sealed class Pet
{public required string Name { get; init; }public required int Age { get; init; }public Pet(){}[SetsRequiredMembers]public Pet(string name) => Name = name;
}var pet = new Pet { Name = "0.0", Age = 1 };
Console.WriteLine($"{pet.Name} -- {pet.Age}");
var pet2 = new Pet("test");
Console.WriteLine($"{pet2.Name} -- {pet2.Age}");

如果不加 SetsRequiredMembers Attribute 在调用对应成员的构造方法时编译器仍然会提示必须要初始化 required 成员,错误如下:

45bc2a6396f0131d720fbfc17e625399.png

但仔细观察前面的示例的话也能看出来其实是有点问题的,就是 Age 是 required 成员,但是我们在构造方法中并没有进行初始化编译器也没有报错,相当于我们欺骗了编译器,我们通过 SetsRequiredMembers 告诉编译器我们在这个构造方法中会初始化所有的 required 成员,但是实际上有些成员并没有进行初始化,然而编译器也没报错,感觉这点上后面可以再优化优化

More

required 成员只是编译器层面的一个检查,实际运行时和普通的成员是一样的,所以就序列化反序列化而言和此前一样,前面示例的成员都是属性,required 也可以用于字段,可以用在结构体中

对我来言,很大的意义是对于可空引用类型而言,就不用再写 = null!; 这样的代码了

大家可以在最新的 .NET 7 Preview 7 中进行体验,前面的示例可以从 Github 上获取:https://github.com/WeihanLi/SamplesInPractice/blob/master/CSharp11Sample/RequiredMemberSample.cs

References

  • https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/required

  • https://github.com/WeihanLi/SamplesInPractice/blob/master/CSharp11Sample/RequiredMemberSample.cs

  • https://github.com/dotnet/csharplang/blob/main/proposals/required-members.md

  • https://github.com/dotnet/csharplang/issues/3630

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/283676.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

互联网大佬简史:马云/雷军/罗永浩/刘强东...

燃财经(ID:rancaijing)原创 作者 | 杜枫 编辑 | 魏佳中国互联网的发展,是一部由大佬撑起的奋斗史,也是一部由大佬主演的打脸史。和传统行业不同,互联网行业日新月异,从业者趋于年轻。马云唱起了摇滚&#x…

Windows 11 新版 22621.575 和 22622.575 推送:照片、URL、文件资源管理器

面向 Beta 频道的 Windows 预览体验成员,微软推送了 Windows 11 预览版 Build 22621.575 和 22622.575。 目前 Beta 频道 Windows 11 预览版分为两组进行测试,通过两组 Windows 预览体验成员的使用数据和反馈,以更好的测试新功能的可靠性。Wi…

linux mysql5.6 安装

2019独角兽企业重金招聘Python工程师标准>>> 1、gcc yum install gcc gcc-c ncurses-devel perl 2、cmake安装 wget http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz tar -xzvf cmake-2.8.10.2.tar.gz cd cmake-2.8.10.2 ./bootstrap ; make ; make insta…

Python常用的12个GUI框架

Graphical User Interface,简称 GUI,又称图形化用户接口,所谓的GUI编程,指的是用户不需要输入代码指令,只通过图形界面的交互就可以操作软件功能。 1.Tkinter 一个轻量级的跨平台图形用户界面(GUI&#xff…

PHP下操作Linux消息队列完成进程间通信的方法

2019独角兽企业重金招聘Python工程师标准>>> 来源:http://www.jb51.net/article/24353.htm 关于Linux系统进程通信的概念及实现可查看:http://www.ibm.com/developerworks/cn/linux/l-ipc/   关于Linux系统消息队列的概念及实现可查看:htt…

.NET 7 发布的最后一个预览版Preview 7, 下个月发布RC

微软在2022年8月9日 发布了.NET 7 Preview 7[1],这是它在11月10日 RTM 之前进入发布候选阶段之前的最后预览版。预览版 7 已在 Visual Studio 17.4 预览版 1 中进行了测试,该预览版也于也与 VS 2022 v17.3 版本一起发布。对于预览版7,开发团队…

2022年全球职业教育行业发展报告

职业教育丨研究报告 核心摘要: 职业教育是职业学校教育与职业培训组成的有机整体,行业参与者除教育培训机构与受训学生外,还涉及企业雇主、行业协会、政府等多方,各群体共同构成密不可分的产业生态。 宏观而言,职业…

实战Cacti网络监控(1)——基础安装配置

实验环境: 物理主机 redhat7.0 内核版本 3.10.0-123.el7.x86_64 虚拟机 redhat6.5 内核版本 2.6.32-431.el6.x86_64 server10.example.com 172.25.254.10 所需软件包: cacti-0.8.8h.tar.g…

《ASP.NET Core 6框架揭秘》实例演示[13]:日志的基本编程模式

《ASP.NET Core 6框架揭秘实例演示[11]:诊断跟踪的几种基本编程方式》介绍了四种常用的诊断日志框架。其实除了微软提供的这些日志框架,还有很多第三方日志框架可供我们选择,比如Log4Net、NLog和Serilog 等。虽然这些框架大都采用类似的设计&…

Caffine Cache 及在SpringBoot中的使用

这一篇我们将要谈到一个新的本地缓存框架:Caffeine Cache。它也是站在巨人的肩膀上-Guava Cache,借着他的思想优化了算法发展而来。 本篇博文主要介绍Caffine Cache 的使用方式,以及Caffine Cache在SpringBoot中的使用。 1. Caffine Cache 在…

C#深入.NET平台的软件系统分层开发

今天我们来讲讲分层开发,你从标题能不能简单的认识一下什么是分层呢? 不懂也没关系,接下来我来给你讲讲。 第一章 软件系统的分层开发 (1)其实分层模式可以这样定义:将解决方案中功能不同的模块分到不同的项…

productFlavors设置signingConfig不管用的问题

2019独角兽企业重金招聘Python工程师标准>>> 在buildTypes release里面添加: productFlavors.dev_.signingConfig signingConfigs.devSign productFlavors.alphaTest_.signingConfig signingConfigs.devSign productFlavors.betaTest_.signingConfig si…

Linux学习之服务器搭建——DHCP服务器

通过前面基础网络配置已经将两台虚拟机连接起来了,在windows 下是将它和Centos设为统一网段,在DHCP里同样不变,改变的是将windows 所配置的静态IP全部换成“自动获取DHCP”而在接下来的操作,就是让我的windows 自动获取来自Linux …

WPF 动态切换黑|白皮肤

WPF 动态切换黑|白皮肤WPF 使用 WPFDevelopers.Minimal 如何动态切换黑|白皮肤作者:WPFDevelopersOrg原文链接: https://github.com/WPFDevelopersOrg/WPFDevelopers.Minimal框架使用大于等于.NET40;Visual Studio 2022;项目使用 MIT 开源…

中小企业虚拟化解决方案-VMware vSphere 6.5-日常管理入口v0.0.1

中小企业虚拟化解决方案-VMware vSphere 6.5日常管理入口v0.0.1本文目的:针对中小企业虚拟化的平台管理,涉及到很多管理入口,普通管理员未必知道从哪里管理?本文将从最底层到最高层进行简单的介绍,最终让普通管理员快速了解管理入…

Svn服务器的搭建与配置

本文由ilanniweb提供友情赞助,首发于烂泥行天下想要获得更多的文章,可以关注我的微信ilanniweb要把svn代码同步到git服务器上,本来是想通过subgit直接同步进行就行了。但是自已以前没有搭建过svn服务器,所以有了这篇文章。我们就来…

JAVA Future类详解

1. Future的应用场景 在并发编程中,我们经常用到非阻塞的模型,在之前的多线程的三种实现中,不管是继承thread类还是实现runnable接口,都无法保证获取到之前的执行结果。通过实现Callback接口,并用Future可以来接收多线…

最新 .NET 社区工具包, 推出MVVM 源代码生成器!

点击上方蓝字关注我们(本文阅读时间:10分钟)我们很高兴地宣布正式推出新的 .NET 社区工具包,现在已经在NuGet上发布了8.0.0版本!这是一个重要版本,包括大量新功能、改进、优化、错误修复,许多反映了全新项目…

Java并发编程:Executor、Executors、ExecutorService

Executors 在Java 5之后,并发编程引入了一堆新的启动、调度和管理线程的API。Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java.util.cocurrent 包下,通过该框架来控制线程的启动、执行和关闭,可以简化…

IOTCS+Ekuiper搭建物联网边缘计算平台

背景介绍IOTCS 是专为物联网平台而设计的工业智能网关。自从 2020 年 10 月以来,我们从需求调研,设计,定型,研发,测试经过漫长的沉淀与孵化,最终顺利实现工业智能网关最初的设想。我们凭借创新设计理念、快…