C#关键字record介绍
在C#9中,新增关键字record,作为模型类,使用起来更方便,后续版本又增加了record struct关键字,作为补充。
本质上,只使用record时,实际上是一个继承接口IEquatable<T>的类,使用record struct时,是一个继承IEquatable<T>的结构。
当我们编写以下的类时
using System.Text;namespace RecordSample
{public record Book{public Book(string name, int pages){Name = name;Pages = pages;}public string Name { get; private set; }public int Pages { get; init; }}public record struct Note{public string Name { get; init; }public int Pages { get; init; }}
}
关键字是record,那么实际上,编译器识别的是什么的,我们使用dnspy反编译工具可以看到book是一个class,对应反编译代码:
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;namespace RecordSample
{[NullableContext(1)][Nullable(0)]public class Book : IEquatable<Book>{[CompilerGenerated]protected virtual Type EqualityContract{[CompilerGenerated]get{return typeof(Book);}}public Book(string name, int pages){this.Name = name;this.Pages = pages;}public string Name { get; private set; }public int Pages { get; set; }[CompilerGenerated]public override string ToString(){StringBuilder stringBuilder = new StringBuilder();stringBuilder.Append("Book");stringBuilder.Append(" { ");if (this.PrintMembers(stringBuilder)){stringBuilder.Append(' ');}stringBuilder.Append('}');return stringBuilder.ToString();}[CompilerGenerated]protected virtual bool PrintMembers(StringBuilder builder){RuntimeHelpers.EnsureSufficientExecutionStack();builder.Append("Name = ");builder.Append(this.Name);builder.Append(", Pages = ");builder.Append(this.Pages.ToString());return true;}[NullableContext(2)][CompilerGenerated]public static bool operator !=(Book left, Book right){return !(left == right);}[NullableContext(2)][CompilerGenerated]public static bool operator ==(Book left, Book right){return left == right || (left != null && left.Equals(right));}[CompilerGenerated]public override int GetHashCode(){return (EqualityComparer<Type>.Default.GetHashCode(this.EqualityContract) * -1521134295 + EqualityComparer<string>.Default.GetHashCode(this.<Name>k__BackingField)) * -1521134295 + EqualityComparer<int>.Default.GetHashCode(this.<Pages>k__BackingField);}[NullableContext(2)][CompilerGenerated]public override bool Equals(object obj){return this.Equals(obj as Book);}[NullableContext(2)][CompilerGenerated]public virtual bool Equals(Book other){return this == other || (other != null && this.EqualityContract == other.EqualityContract && EqualityComparer<string>.Default.Equals(this.<Name>k__BackingField, other.<Name>k__BackingField) && EqualityComparer<int>.Default.Equals(this.<Pages>k__BackingField, other.<Pages>k__BackingField));}[CompilerGenerated]protected Book(Book original){this.Name = original.<Name>k__BackingField;this.Pages = original.<Pages>k__BackingField;}}
}
可以看到,编译器帮我们自动实现了运算符重载,包括==,!=,以及ToString操作,如果各个属性值都相等,那么认为两个对象相等。
相对的,record struct是一个结构,也是类似效果
下面演示对应对象效果
using RecordSample;
Book book1 = new Book("C# in Depth", 900);
Book book2 = new Book("C# in Depth", 900);
Console.WriteLine(book1 == book2); // True
Console.WriteLine(book1); // Book { Name = C# in Depth, Pages = 900 }
var book3 = book1 with { Pages = 1000 };
Console.WriteLine(book1 == book3); // False
Note n1= new Note { Name = "Note1", Pages = 10 };
Note n2= new Note { Name = "Note1", Pages = 10 };
Console.WriteLine(n1 == n2); // True
Console.WriteLine(n1); // Note { Name = Note1, Pages = 10 }
var n3 = n1 with { Pages = 20 };
Console.WriteLine(n1 == n3); // False