写点什么

.NET6 新东西 --struct 优化

作者:喵叔
  • 2021 年 11 月 20 日
  • 本文字数:1350 字

    阅读完需:约 4 分钟

在.NET6 中针对 Struct 做了一些优化,下面我们就通过一些案例来看一下.NET6 中针对 Struct 的优化。

一、Record Struct

虽然在上一个版本中就有了 record,但是上一版本中的的 record 是 class 是一个引用类型,但是 record struct 是值类型是一个结构,它的使用方式如下:


record struct Point(int X, int Y);
复制代码


在.NET6 中也支持 record 来声明一个基于 class 的 record,这和原来的 record 是一样的,例如record class RecordModel(int Id, string Name) 这和 record RecordModel(int Id, string Name)record struct 会自动生成 Equals 和 GetHashCode 并重写==和!=操作符,并且可以用 with 修改部分属性创建新的对象。如果 record struct 声明有参数构造器,则会生成一个隐式的无参构造。代码如下:


var p1 = new Point(1, 2);var p2 = p with { X = 2 };Console.WriteLine(p1);Console.WriteLine(p2);Console.WriteLine(new Point());
复制代码


运行上述代码可以看到即使没有显式声明无参构造还是会生成一个无参构造来初始化。上述代码输出如下:


Point { X = 1, Y = 2 }Point { X = 2, Y = 2 }Point { X = 0, Y = 0 }
复制代码

二、readonly struct record

我们可以使用 readonly 来标记结构体,也可以使用 readonly struct record,但 record struct 不能使用 ref 修饰。使用 readonly struct record 声明的结构体,如果使用 Primary Constructor 对应的属性会是 init。例如readonly record struct Point(int X, int Y);属性的声明是这样的:


internal readonly struct Point : IEquatable<Point>{  public int X { get; init; }  public int Y { get; init; }  public Point(int X, int Y)  {    this.X = X;    this.Y = Y;  }}
复制代码

三、Parameterless Constructor

.NET6 支持用户自定义无参构造方法,我们可以在无参构造方法中加入初始化逻辑,代码如下如下:


Console.WriteLine(new Point1().ToString());Console.WriteLine(default(Point1).ToString());Console.WriteLine(Activator.CreateInstance<Point1>());struct Point1{    public int X { get; set; }    public int Y { get; set; }    private int Z { get; set; }    public Point1()    {        X = 1;        Y = 2;        Z = 3;    }    public override string ToString()    {        return $"{X}_{Y}_{Z}";    }}
复制代码


这里需要注意 default 和 new 的差别,default 是结构体空状态,不会执行无参构造,new 是会执行,通过反射创建对象的时候也会执行构造,代码输出结果如下:


1_2_30_0_01_2_3
复制代码


除了 record 之外,.NET6 还扩展了 with 表达式用法,普通结构体和匿名对象也可以使用 with 来修改部分属性.代码如下:


Console.WriteLine((new Point1() with { X = 2 }).ToString());Console.WriteLine();var obj = new{    X = 1,    Y = 1};Console.WriteLine(JsonSerializer.Serialize(obj));Console.WriteLine(JsonSerializer.Serialize(obj with { X = 3, Y = 3 }));
复制代码


输出结果如下:


2_2_3{"X":1,"Y":1}{"X":3,"Y":3}
复制代码


with 只能对 public 成员进行操作,上面代码中的 Z 是 private,因此在 with 表达式中是不能指定。和 record class 相比 record struct 没有 Clone 方法,因为 struct 不需要自带 Clone 功能,record struct 不允许声明 Clone 成员方法,所有 record 都不允许声明 Clone 成员。

用户头像

喵叔

关注

还未添加个人签名 2020.01.14 加入

还未添加个人简介

评论

发布
暂无评论
.NET6新东西--struct优化