查看原文
其他

C# 9.0 新特性预览 - init-only 属性

DotNet 2021-09-23

(给DotNet加星标,提升.Net技能

转自:Rwing
cnblogs.com/Rwing/p/csharp-9-0-preview-init-only.html

前言


随着 .NET 5 发布日期的日益临近,其对应的 C# 新版本已确定为 C# 9.0,其中新增加的特性(或语法糖)也已基本锁定,本系列文章将向大家展示它们。


目录


《C# 9.0 新特性预览 - 类型推导的 new》


《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
}
}
}


- EOF -



推荐阅读  点击标题可跳转
打造跨平台.NET Core后台服务.NET Core 微服务快速开发框架 Viper 限流Span 对 C# 进程中三大内存区域进行统一访问 ,太厉害了!


看完本文有收获?请转发分享给更多人

关注「DotNet」加星标,提升.Net技能 

好文章,我在看❤️

: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存