C# 9 新特性——init only setter
C# 9 新特性——init only setter
Intro
C# 9 中新支持了 init 关键字,这是一个特殊的 setter,用来指定只能在对象初始化的时候进行赋值,另外支持构造器简化的写法,比如:Target-typed new expression 在已知类型的情况下可以使用 new() 来代表构造方法的简化用法,可以简化字段的声明,也可以简化一次声明多个相同类型的变量
Sample
来看一个示例,我们定义一个测试用的 Person 类,测试代码如下:
public class Person
{
public int Age { get; init; }
public string Name { get; init; }
public string Description { get; set; }
public override string ToString()
{
return $"Name:{Name}(Age:{Age})";
}
}
init 是一个特殊的 setter 适用于实例属性,被标记为 init 的属性,只能在实例化的时候通过初始化器来赋值,实例化操作完成后不允许再修改值。
var p1 = new Person()
{
Name = "Michael",
Age = 10
};
Console.WriteLine(p1);
// compiler error,不能对 init 的字段再赋值
// p1.Age = 12;
// Target-Typed new expression, C#9 新特性
Person p2 = new()
{
Name = "Jane",
Age = 10,
}, p3 = new()
{
Name = "Alice"
};
Console.WriteLine(p2);
Console.WriteLine(p3);
init 的等效写法,init 类似于 set ,但是 init 对应的字段会是一个 readonly 的字段,来保证只能在构造器中或者初始化器中被赋值,另外编译器会做检查如果是 init,会有一个特殊的标识,在初始化后再赋值的时候就会报错,类似于下面这样:
internal class TestInitModel
{
private readonly string _name;
public string Name
{
get => _name;
init => _name = value;
}
}
我们以上面的 Person 为例来看一下生成 IL 代码的区别:

可以看到声明为 init 的 属性会比普通的 set 多出来一个修饰符,这是由编译器去生成的,编译器也会根据此去判断是否是在初始化的时候赋值,如果不是就会报错。
序列化是否会有问题呢,我们来测试一下,可以看到 model1 是被正常赋值(这里的 ToJson/JsonToObject是基于 Newtonsoft.Json 的 JsonConvert 封装的扩展方法)

More
我觉得 init 为我们带来的好处在于,可以在初始化的时候赋值而非直接通过构造器赋值,如果希望一个属性只能 get ,不在初始化之外的地方被赋值,之前我的做法都是在构造器里初始化,只保留一个 getter,没有 setter,有了这个支持之后就可以不需要修改构造方法比较方便的使用了
Reference
- https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-9
- https://github.com/WeihanLi/SamplesInPractice/tree/master/CSharp9Sample
- https://github.com/WeihanLi/SamplesInPractice/blob/master/CSharp9Sample/InitOnlySample.cs
C# 9 新特性——init only setter的更多相关文章
- C# 9.0中引入的新特性init和record的使用思考
写在前面 .NET 5.0已经发布,C# 9.0也为我们带来了许多新特性,其中最让我印象深刻的就是init和record type,很多文章已经把这两个新特性讨论的差不多了,本文不再详细讨论,而是通过 ...
- iOS - Swift Swift 语言新特性
1.Swift 2.0 带来哪些新变化 常规变化: 1.OS X 10.11.iOS 9 和 watchOS 2 SDK 采纳了一些 Objective-C 的特性用来提高 Swift 的编程体验, ...
- 最新iOS 6 in Xcode4.5新特性——Storyboard和属性自动绑定
最新iOS 6 in Xcode4.5新特性编程之二(上)——Storyboard和属性自动绑定 从Xcode 4.3开始,Storyboard 就是iOS 5和iOS 6中令人兴奋的一个新特性,他将 ...
- JDK各个版本的新特性
对于很多刚接触java语言的初学者来说,要了解一门语言,最好的方式就是要能从基础的版本进行了解,升级的过程,以及升级的新特性,这样才能循序渐进的学好一门语言.今天先为大家介绍一下JDK1.5版本到JD ...
- C#6.0,C#7.0新特性
C#6.0新特性 Auto-Property enhancements(自动属性增强) Read-only auto-properties (真正的只读属性) Auto-Property Initia ...
- JDK5 新特性
JDK5新特性目录导航: 自动拆装箱 Foreach 静态导入 可变参数 Var args 枚举 格式化输出 泛型 ProcessBuilder 内省 线程并发库(JUC) 监控和管理虚拟机 元数据 ...
- C# 9.0 新特性预览 - init-only 属性
C# 9.0 新特性预览 - init-only 属性 前言 随着 .NET 5 发布日期的日益临近,其对应的 C# 新版本已确定为 C# 9.0,其中新增加的特性(或语法糖)也已基本锁定,本系列文章 ...
- 11g新特性-使用DNFS
NFS相信应该都很熟悉了,但是我们对它的性能一直有所诟病.Oracle在10g版本通过允许对数据库文件直接IO引入ASM.在11g版本中,Oracle对NFS提供了类似的增强,为了改进NFS的性能,开 ...
- IOS第三天-新浪微博 - 版本新特性,OAuth授权认证
*********版本新特性 #import "HWNewfeatureViewController.h" #import "HWTabBarViewController ...
随机推荐
- Spring Boot 2.x 多数据源配置之 JPA 篇
场景假设:现有电商业务,商品和库存分别放在不同的库 配置数据库连接 app: datasource: first: driver-class-name: com.mysql.cj.jdbc.Drive ...
- mysql事务原理以及锁
一.Innodb事务原理 1.什么是事务 a.事务(Transaction)是数据库区别于文件系统的重要特性之一,事务会把数据库从一种一致性状态转换为另一种一致性状态. b.在数据库提交时,可以确保要 ...
- PyQt(Python+Qt)学习随笔:QTableWidget的currentItem、rowCount、columnCount等部件状态属性访问方法
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 老猿将QTableWidget表格部件中反映部件当前情况的一些方法归类为部件状态访问方法,包括部件的 ...
- Leetcode学习笔记(2)
题目1 ID面试题 01.04 给定一个字符串,编写一个函数判定其是否为某个回文串的排列之一. 回文串是指正反两个方向都一样的单词或短语.排列是指字母的重新排列. 回文串不一定是字典当中的单词. 示例 ...
- CTFHub Web题学习笔记(SQL注入题解writeup)
Web题下的SQL注入 1,整数型注入 使用burpsuite,?id=1%20and%201=1 id=1的数据依旧出现,证明存在整数型注入 常规做法,查看字段数,回显位置 ?id=1%20orde ...
- 一篇文章掌握Nginx核心文件结构
1 Nginx核心配置结构 2 配置模块详解 设置worker进程的用户,指的linux中的用户,会涉及到nginx操作目录或文件的一些权限,默认为nobody user root; worker进程 ...
- STL—— 容器(vector)元素的删除
1. clear() 将整个 vector 都删除 使用 vectorname.clear() 可以将整个vector 中的元素全部删除,但是内存不会释放,如下代码: 1 #include <i ...
- 06 python开发之函数
06 python开发之函数 目录 06 python开发之函数 6 函数 6.1 基本使用 6.1.1 基本概念 6.1.2 定义函数 6.2 调用函数与函数返回值 6.2.1 调用函数三种形式 6 ...
- win+mac全网视频无水印采集工具
把网址填入输入框,点击下载即可.支持全网几十个平台,方便使用 window版:https://sansuinb.lanzous.com/i00Rjej0fib mac版:https://sansuin ...
- 抖音视频背景音乐提取工具v1.0
使用方法:id就是你点那个音乐分享,复制链接,然后链接有个ID(userid=后面数字就是id),就是那个,输入ID之后得到链接,浏览器新建下载,复制你得到的链接就行了(结果空白多解析几次就行了)