C# 9.0 新特性预览 - init-only 属性
C# 9.0 新特性预览 - init-only 属性
前言
随着 .NET 5 发布日期的日益临近,其对应的 C# 新版本已确定为 C# 9.0,其中新增加的特性(或语法糖)也已基本锁定,本系列文章将向大家展示它们。
目录
[C# 9.0 新特性预览 - 类型推导的 new]
[C# 9.0 新特性预览 - 空参数校验]
[C# 9.0 新特性预览 - 顶级语句]
[C# 9.0 新特性预览 - init-only 属性]
[C# 9.0 新特性预览 - Record 类型]
[C# 9.0 新特性预览 - 模式匹配的改善]
[C# 9.0 新特性预览 - 源代码生成器]
[C# 9.0 新特性预览 - 其他小的变化]
只初始化 setter (Init Only Setters)
这个特性允许创建只初始化(init only)的属性和索引器,使得 C# 中的不可变模型更加灵活。
背景
在此之前,我们创建实体类/POCO类/DTO类等等模型类的时候,都期望属性只读不允许从外部修改,会将属性的 setter 设为私有或者干脆不设置 setter,例如:
public class Person
{
public string Name { get; private set; }
// OR
//public string Name { get; }
}
再添加一个拥有全部属性作为签名的构造方法:
...
public Person(string name)
{
this.Name = name;
}
...
这样做虽然可以达到目的,但是带来了两个问题
1.假如属性增多,会带来工作量的成倍增加,以及不易维护
2.无法使用对象初始化器(object initializers)
var person = new Person
{
Name = "Rwing" // Compile Error
};
在这个情况下,init 关键字应运而生了。
语法
语法很简单,只需要将属性中的 set 关键字替换为 init 即可:
public string Name { get; init; }
以上代码会被大致翻译为:
private readonly string _name;
public string Name
{
get { return _name; }
set { _name = value;}
}
可以看到,与 set 的区别是,init 会为背后的字段添加 readonly 关键字。
这样我们就可以去掉一堆属性的构造方法转而使用对象初始化器了,并且达到了不可变的目的。
var person = new Person
{
Name = "Rwing"
};
// 初始化后无法再次修改
person.Name = "Foo"; // Error: Name is not settable
这一语法,有很多场景需要配合同样在 C# 9.0 中新增的 record 类型使用。
哪些情况下可以被设置
- 通过对象初始化器
- 通过 with 表达式
- 在自身或者派生类的构造方法中
- 在标记为 init 的属性中
- 在特性(attribute)类的命名参数属性中
以上场景不难理解,但是值得一提的是,只有 get 的属性是不可以派生类的构造方法中赋值的,但是 init 可以:
class Base
{
public bool Foo { get; init; }
public bool Bar { get; }
}
class Derived : Base
{
Derived()
{
Foo = true;
Bar = true; // ERROR
}
}
此外有一种例外, 在以上场景中的 lambda 或本地函数中,也不允许被设置,例如:
原因也很简单,lambda 或本地函数在编译后已经不在构造函数中了。
public class Class
{
public string Property { get; init; }
Class()
{
System.Action a = () =>
{
Property = null; // ERROR
};
local();
void local()
{
Property = null; // ERROR
}
}
}
参考
[Proposal: Init Only Setters]
[InitOnlyMemberTests.cs]
C# 9.0 新特性预览 - init-only 属性的更多相关文章
- C# 9.0 新特性预览 - 类型推导的 new
C# 9.0 新特性预览 - 类型推导的 new 前言 随着 .NET 5 发布日期的日益临近,其对应的 C# 新版本已确定为 C# 9.0,其中新增加的特性(或语法糖)也已基本锁定,本系列文章将向大 ...
- C# 9.0 新特性预览 - 空参数校验
C# 9.0 新特性预览 - 空参数校验 前言 随着 .NET 5 发布日期的日益临近,其对应的 C# 新版本已确定为 C# 9.0,其中新增加的特性(或语法糖)也已基本锁定,本系列文章将向大家展示它 ...
- C# 9.0 新特性预览 - 顶级语句
C# 9.0 新特性预览 - 顶级语句 前言 随着 .NET 5 发布日期的日益临近,其对应的 C# 新版本已确定为 C# 9.0,其中新增加的特性(或语法糖)也已基本锁定,本系列文章将向大家展示它们 ...
- Vue.js 3.0 新特性预览
总结起来,Vue 3 以下方面值得我们期待 : 更快 更小 更易于维护 更多的原生支持 更易于开发使用 完整的PPT:docs.google.com/presentatio… Evan 和 Vue 团 ...
- avalon1.3的新特性预览
avalon1.2的性能优化风暴很快就告一段落,入职也快一个月了,许多乱七八糟的事也少了下来,估计未来一个月会有许多好东呈现给大家. 首先是一个性能检测工具.由于MVVM是将原本由人脑干的事,转到各种 ...
- Windows Phone 8.1SDK新特性预览
前言 Windows Phone 8.1的预览版将在近期推送,WP 8.1的SDK也已经进入到RC阶段,可以从这里安装.本次更新的SDK被直接集成到了VS2013Update2里面,不再是单独的 ...
- Office 2016 正式发布——新特性预览
今天微软又发生了一件大事!Windows Office 2016正式发布,这标志着Windows Office 又达到了一个新的里程碑! 全新的Office 发布为Office 365 用户带来了新的 ...
- CSS3_新特性预览
一.强大的CSS选择器 以前我们通常用class. ID 或 tagname 来选择HTML元素,CSS3的选择器强大的难以置信. 它们可以减少在标签中的class和ID的数量更方便的维护样式表.更 ...
- C# 7.0 新特性2: 本地方法
本文参考Roslyn项目中的Issue:#259. 1. C# 7.0 新特性1: 基于Tuple的“多”返回值方法 2. C# 7.0 新特性2: 本地方法 3. C# 7.0 新特性3: 模式匹配 ...
随机推荐
- HotSpot VM 中的JIT分类
在HotSpot VM中内嵌有两个JIT编译器,分别为Client Compiler和Server Compiler,但大多数情况下我们简称为C1编译器和C2编译器.开发人员可以通过如下命令显式指定J ...
- Java11新特性
局部变量类型推断增强 Java11中可以在lambda表达式的形参中使用var,好处是可以在形参上加注解 使用示例 (@Deprecated var x, @Nullable var y)->x ...
- jpeg编解码概述
本博文为概览性介绍.后面有空了再分几篇博文分别介绍所用到的技术细节. 1.编解码目标 编码和解码是个逆过程.jpeg编码的目的在于图形去冗余,进行数据压缩,解码的目的在于还原图像,使能够进行预览. 2 ...
- 能否使用GHDL+GTKWave代替Quartus ii
能否使用GHDL+GTKWave代替Quartus ii macOS High Sierra系统 10.13.6 [toc] 先给出答案 可以替代一部分功能 如果你是一个学工科的学生,正在学习EDA. ...
- Spring学习(五)--Spring的IOC
1.BeanDefinition在IOC的注册 当BeanDefinition完成载入和解析之后,用户定义的BeanDefinition在IOC容器中已经建立自己的数据结构和数据表示,但是无法使用,需 ...
- mysql 空值(null)和空字符('')的区别
日常开发中,一般都会涉及到数据库增删改查,那么不可避免会遇到Mysql中的NULL和空字符. 空字符(")和空值(null)表面上看都是空,其实存在一些差异: 定义: 空值(NULL)的长度 ...
- Sprign-mvc系列之Spring快速入门 什么是sprign-mvc spring-mvc的作用及其基本使用+组件解析+注解解析
Spring-mvc 什么是SpringMvc SpringMvc是一种基于java的实现Mvc设计模式的请求驱动类型的轻量级web框架,属于SpringFrameWork的后续产品,已经融合在Spr ...
- Oracle 正确删除归档日志的方法
我们都知道在controlfile中记录着每一个archivelog文件的相关信息,当然们在OS下把这些物理文件delete掉后,在我们的controlfile中仍然记录着这些archivelog文件 ...
- C#实例(经典):四路光电开关&激光雷达数据采集和波形图绘制
前言:本文全部纯手工打造,如有疏漏之处,还请谅解! 如果需要查看更多文章,请微信搜索公众号 csharp编程大全,需要进C#交流群群请加微信z438679770,备注进群, 我邀请你进群! ! ! 这 ...
- springboot1.5和jpa利用HikariCP实现多数据源的使用
背景 现在已有一个完整的项目,需要引入一个新的数据源,其实也就是分一些请求到从库上去 技术栈 springboot1.5 (哎,升不动啊) 思路 两个数据源,其中一个设置为主数据源 两个事物管理器,其 ...