C# 记录类

C# 中的记录是一个结构,它为使用数据模型提供特定的语法和行为。

在下列情况下,请考虑使用记录而不是类或结构:

  • 你想要定义依赖值相等性的数据模型。
  • 你想要定义对象不可变的类型。

1、不可变性

var per1 = new Person("adsfas", "aaa");
//per1.LastName = "ceshi";//编译错误 

var per2 =new Person1()
{
    FirstName="abc",
    LastName="abc",
};
//per2.LastName="abc";//编译错误

var abc = new DataMeasurement(DateTime.Now, 16.5);
//值类型 ,可以修改
abc.Measurement = 65.7;
Console.WriteLine(abc.Measurement);

var point1 = new Point()
{
    X = 1,
    Y = 2,
    Z = 3
};
//point1.X = 8;//编译错误

Console.ReadLine();

public record struct DataMeasurement(DateTime TakenAt, double Measurement);

public record Person(string FirstName, string LastName);
public record Person1
{
    public string FirstName { get; init; } = default!;
    public string LastName { get; init; } = default!;
};

public record struct Point
{
    public double X { get; init; }
    public double Y { get; init; }
    public double Z { get; init; }
}
View Code

如果需要一个以数据中心的类型是线程安全的,或者需要使哈希表中的哈希代码保存不变,那么不可变很有用,但不变性不适用所有的数据场景。如Entity Framework Core.

init-only属性无论是通过位置参数创建的,还是通过置顶init访问器创建的,都具有浅的不可变性。初始化后,讲不能更改值类型属性的值或者引用型属性的引用。不过引用型属性引用的数据是可用更改的。

2、继承

一条记录可以从另一条记录继承,但是记录不能从类继承,类也不能从记录继承

3、值相等性

 

  • 对于 class 类型,如果两个对象引用内存中的同一对象,则这两个对象相等。
  • 对于 struct 类型,如果两个对象是相同的类型并且存储相同的值,则这两个对象相等。
  • 对于 record 类型(包括 record struct 和 readonly record struct),如果两个对象是相同的类型并且存储相同的值,则这两个对象相等。

 

一些数据模型需要引用相等性。 例如,Entity Framework Core 依赖于引用相等性来确保它对概念上是一个实体的实体类型只使用一个实例。 因此,记录和记录结构不适合用作 Entity Framework Core 中的实体类型。

var phoneNumbers = new string[2];
Person person1 = new("Nancy", "Davolio", phoneNumbers);
Person person2 = new("Nancy", "Davolio", phoneNumbers);
Console.WriteLine(person1 == person2); // output: True
Console.ReadLine();

public record Person(string FirstName, string LastName, string[] PhoneNumbers);
View Code

继承层次结构中的相等性

 

 4、属性定义的位置语法

 

 5、序列化处理

当我们需要把记录进行json序列号操作时,需要把字段名称序列化为自定的名称,可以使用json特性进行标记。如下

 

 6、With操作

 

使用修改的特定属性和字段生成其操作数的副本

 

副本和原始操作数都具有对同一引用类型实例的访问权限

 

 

 

 7、自定义复制语句

 

任何记录类类型都具有复制构造函数如果需要自定义记录复制语句,请显式声明具有所需行为的复制构造函数。 

 

 8、非破坏性变化

 

如果需要复制包含一些修改的实例,可以使用 with 表达式来实现非破坏性变化。 with 表达式创建一个新的记录实例,该实例是现有记录实例的一个副本,修改了指定属性和字段。

 

Person person1 = new("Nancy", "Davolio") { PhoneNumbers = new string[1] };

 

Console.WriteLine(person1); // output: Person { FirstName = Nancy, LastName = Davolio, PhoneNumbers = System.String[] }

 

Person person2 = person1 with { FirstName = "John" };

 

Console.WriteLine(person2);// output: Person { FirstName = John, LastName = Davolio, PhoneNumbers = System.String[] }

 

Console.WriteLine(person1 == person2); // output: False

 

person2 = person1 with { PhoneNumbers = new string[1] };

 

Console.WriteLine(person2);// output: Person { FirstName = Nancy, LastName = Davolio, PhoneNumbers = System.String[] }

 

Console.WriteLine(person1 == person2); // output: False

 

person2 = person1 with { };

 

Console.WriteLine(person1 == person2); // output: True

 

Console.ReadLine();

 

public record Person(string FirstName, string LastName)

 

{

 

    public string[] PhoneNumbers { get; init; }

 

}

 

posted @ 2022-11-30 12:57  都市之夜  阅读(175)  评论(0编辑  收藏  举报