init是什么意思?

init就 modreq([System.Runtime]System.Runtime.CompilerServices.IsExternalInit) 类型的缩写

modreq= Modified Request:修改请求

IsExternalInit=is Externa Init(initialize):是外部初始化 。

所以init 完整的意思就是  修改请求(在外部初始化的时候)

总的功能就是扩大readonly实例字段的赋值方式,C#9之前readonly实例字段只能在字段初始值设定项和实例构造函数中赋值(静态只读字段还是只有两种赋值方式)。C#9 推出init 以后,readonly实例字段可以多一种赋值方式,可以在对象初始值设定项中赋值。

动机
自1.0 以来,用 c # 生成不可变数据的基础机制并未更改。 它们仍保留:
1.将字段声明为 readonly 。
2. 声明仅包含 get 访问器的属性。
这些机制在允许构造不可变的数据时有效,但它们通过向类型的样板代码添加成本并从对象和集合初始值设定
项的功能中选择此类类型来实现此目的。 这意味着开发人员必须在易用性和不可变性之间进行选择。
像声明类型一样,简单的不可变对象(例如 Point )需要两个样板板代码,以支持构造。 类型越大,此样板板式的
成本就越大:

struct Point
{
public int X { get; }
public int Y { get; }
}
public Point(int x, int y)
{
this.X = x;
this.Y = y;
}

init 的作用

总的功能就是扩大readonly实例字段的赋值方式,C#9之前readonly字段只能在字段初始值设定项和实例构造函数中赋值。C#9 推出init 以后,readonly实例字段可以多一种赋值方式,可以在对象初始过程中通过属性和索引器赋值,也就是说可以通过对象的初始值设定项 赋值。

1、 init访问器(只替代set访问器),用在属性和索引器中。 对象的构造阶段 init访问器可以使用,对象实例完成后init访问器不可使用。对象初始化完成后init对应的属性就是readonly字段。

类的初始化顺序:https://www.cnblogs.com/cdaniu/p/15308485.html

2、允许 init 作为字段修饰符

3、init修饰符可以扩展以应用于所有实例成员

4、允许 init 作为类型修饰符

init 访问器

init访问器(只替代set访问器),用在属性和索引器中。 对象的构造阶段 init访问器可以使用,对象实例完成后init访问器不可使用。对象初始化完成后init对应的属性就是readonly字段。

    public class Test
{ static void Main(string[] args)
{
var d = new Derived();
} }
class Base
{
public bool Value { get; init; }
} class Derived : Base
{
public Derived()
{
// Not allowed with get only properties but allowed with init
Value = true;
}
}

modreq= Modified Request:修改请求

IsExternalInit=is Externa Init(initialize):是外部初始化,init其实就是 IsExternalInit的简写。init是个修饰符。

所以init 完整的意思就是  修改请求(在外部初始化的时候)

上面这张图就已经很清晰的解释了,init就 modreq([System.Runtime]System.Runtime.CompilerServices.IsExternalInit) 。init的功能就是这个修饰符的功能。

当init在做属性访问器器时,它是带了修饰符的set访问器。完成对 私有只读字段 的封装。换句话说我们可以把readonly实例字段放在 init访问器中初始化。

init只能用于实例化属性(索引)中

readonly字段初始化只有两种方式:声明时和构造函数中,但从 C# 9开始 readonly 实例字段 多了一个属性赋值方式,也就是对象初始值设定项中赋值。实例化完成后就不能使用属性化赋值

使用了init修饰的属性,则不需要定义构造函数,直接在对象初始化器中赋值即可。
这样就可以再对象和集合初始值设定项中初始化属性。拓展初始值设定像功能,。

init访问器可设置的规则围绕类型层次结构扩展。 如果该成员是可访问的,并且已知该对象处于构造阶段,则该成员是可设置的。 这就是:

对象最初进行实例化的时期。这个初始化过程称为构造阶段

class Base
{
public bool Value { get; init; }
} class Derived : Base
{
Derived()
{
// Not allowed with get only properties but allowed with init
Value = true;
}
} class Consumption
{
void Example()
{
var d = new Derived() { Value = true; };
}
}

2、允许 init 作为字段修饰符

同样, init 也可以作为属性访问器,它也可以作为字段的指定,将其作为 init 属性提供。 这将允许在类型、派生类型或对象初始值设定项完成构造之前,对字段进行赋值。

class Student
{
public init string FirstName;
public init string LastName;
} var s = new Student()
{
FirstName = "Jarde",
LastName = "Parsons",
}

在元数据中,这些字段将以与readonly字段相同的方式进行标记,  但使用附加的属性 modreq  指示它们是 init 样式字段。

4、允许 init 作为类型修饰符

将init用修饰类型时,类型中所有实列字段成员都可以被修饰撑init,这一点不同于readonly,readonly修饰的所有实例成员都是readonly。

再结构类型中使用init

struct Point
{
public init int X;
public init int Y;
} // vs. init struct Point
{
public int X;
public int Y;
}

C# init用法的更多相关文章

  1. C++程序设计(二)

    1. 类 class CRectangle { public: int w, h; void Init( int w_, int h_ ) { w = w_; h = h_; } int Area() ...

  2. Spring 中 Xml配置文件属性的说明

    Xml配置文件属性的说明: <bean id="TheAction" ⑴ class="net.xiaxin.spring.qs.UpperAction" ...

  3. git基础入门之常用命令操作

    本内容参考:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 初学,有什么不对的地方 ...

  4. eclipse中git插件使用

    1,首先看下文件的几个工作区:Unstaged Changes(本地工作空间),Staged Changes(Add to Index操作之后代码存放的地方),Local Repository(本地仓 ...

  5. handsontable-developer guide-cell editor

    单元格编辑 cell editor renderer:展示数据:editor:改变数据:renderer用一个函数表示:后者有一系列的操作,需要用class来表示: EditorManager han ...

  6. Xml配置文件属性的说明

    Xml配置文件属性的说明: <bean id="TheAction" ⑴ class="net.xiaxin.spring.qs.UpperAction" ...

  7. 17_defer(延迟调用)关键字的使用

    1.defer是延迟调用关键字,只能在函数内部使用 2.总是在main函数结束前调用(和init用法相对) 3.如果有多个defer 遵循先进后出的原则 4.和匿名函数同时使用时,如果匿名函数带有参数 ...

  8. 升级go mod采坑录

    为了使用go mod把golang升级到了最新的1.12版本,go mod是1.11版本引入的,go mod的引入极大的方便了golang项目的依赖管理,同时把golang项目从GOPATH中解放了出 ...

  9. init/loadView/viewDidLoad/initWithNibName/awakeFromNib/initWithCoder的用法

    init/loadView/viewDidLoad/viewDidUnload 这么细节的东西想来大家都不在意,平时也不会去关系,但是在面试时却常常被提到,所以了解viewController的生命周 ...

随机推荐

  1. T-SQL的游标和fetch

    很多时候我们sql操作会得到一个结果集合,当我们需要依次查看集合内的内容时,我们便需要游标特性了. 所以,sql的游标类似c++里容器的迭代器,下面举个例子来辅助理解: DECLARE vend_cu ...

  2. 返回值Object-注解驱动作用

    返回值Object 两个常用实现类 StringHttpMessageConverterhe:负责读取字符串格式的数据和写出字符串格式的数据 MappingJackson2HttpMessageCon ...

  3. Tomcat-Tomcat服务器实例使用的其他细节说明

    1,修改工程访问路径 context修改路径 ,访问的地址也会改变成一致 2,修改运行的端口号 3,修改运行时使用的浏览器 4,配置资源热部署

  4. 操作系统的发展史(并发与并行)<异步与同步>《进程与程序》[非堵塞与堵塞]

    目录 一:一:手工操作 -- 穿孔卡片 1.简介 二:手工操作方式两个特点: 三:批处理 -- 磁带存储 1.联机批处理系统 2.脱机批处理系统 3.多道程序系统 4.多道批处理系统 四:总结发展史 ...

  5. K8S访问机制

    pod -> endpoint -> service -> namespace -> svc.cluster.local .....在 a 名称空间,访问 b 名称空间的 b1 ...

  6. 人口信息普查系统-JavaWeb-二

    上次发表了人口普查系统的题目要求,今天和大家分享一下我的技术方案. 技术上用到的是html+jsp+JavaBean+servlet+JavaScript 其实现在的前端页面主流还是html,它可以实 ...

  7. Kubernetes之日志和监控(十五)

    一.日志和监控 1.1.Log 1.1.1.容器级别 通过docker命令查看容器级别的日志 docker ps --->containerid docker logs containerid ...

  8. plsql 视图中 为什么使用替代触发器

    /* 什么是视图? 视图:数据库对象,存的是一个查询命令:当作一个虚拟的数据表来使用: 应用场景: 简化查询操作:不能直接在视图上进行create,insert,update操作: 创建视图? 需要管 ...

  9. NOIP2018 Day2T2 填数游戏

    下面先给出大家都用的打表大法: 首先我们可以发现 \(n \le 3\) 的情况有 \(65pts\),而 \(n\) 这么小,打一下表何乐而不为呢?于是我写了一个爆枚每个位置再 \(check\) ...

  10. CSP2019 Day2T3 树的重心

    显然如果我们直接枚举断哪条边,剩下的两颗树的重心编号非常不好求,一个常见的想法是我们反过来,考虑每个节点有多少种情况作为树的重心,计算每个点对答案的贡献. 下面我们就需要大力分类讨论了.假设我们现在考 ...