博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 9 新特性——init only setter
阅读量:4035 次
发布时间:2019-05-24

本文共 1707 字,大约阅读时间需要 5 分钟。

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.JsonJsonConvert 封装的扩展方法)

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

转载地址:http://gkudi.baihongyu.com/

你可能感兴趣的文章
Centos import torchvision 出现 No module named ‘_lzma‘
查看>>
Maximum Subsequence Sum
查看>>
PTA:一元多项式的加乘运算
查看>>
CCF 分蛋糕
查看>>
解决python2.7中UnicodeEncodeError
查看>>
小谈python 输出
查看>>
Django objects.all()、objects.get()与objects.filter()之间的区别介绍
查看>>
python:如何将excel文件转化成CSV格式
查看>>
Django 的Error: [Errno 10013]错误
查看>>
机器学习实战之决策树(一)
查看>>
[LeetCode By Python] 2 Add Two Number
查看>>
机器学习实战之决策树二
查看>>
[LeetCode By Python]7 Reverse Integer
查看>>
[LeetCode By Python]9. Palindrome Number
查看>>
[leetCode By Python] 14. Longest Common Prefix
查看>>
[LeetCode By Python]108. Convert Sorted Array to Binary Search Tree
查看>>
[leetCode By Python]111. Minimum Depth of Binary Tree
查看>>
[LeetCode By Python]118. Pascal's Triangle
查看>>
[LeetCode By Python]121. Best Time to Buy and Sell Stock
查看>>
[LeetCode By Python]122. Best Time to Buy and Sell Stock II
查看>>