.NET 6中为record类型自定义Equals方法

2022-04-17 13:50:37
目录
一、重写Equals方法二、自定义Equals方法三、结论

前言:

record类型,这是一种新引用类型,而不是类或结构。record与类不同,区别在于record类型使用基于值的相等性。

例如:

public record DemoRecord(int id);public class DemoClass{  public DemoClass(int id)  {    this.id = id;  }  public int id {易采站长站 get; }}

但是,当record类型中的属性是引用类型时,相等性就失效了。

例如:

public record A(int[] ids);

一、重写Equals方法

首先想到的解决方法是像类一样重写Equals方法:

public class DemoClass{  public override bool Equals(object obj)  {    if (obj == null || obj is not DemoClass demoClass)    {      return false;    }    return id.Equals(demoClass.id);  }}

但是发现record类型居然不提供重写Equals方法的能力

二、自定义Equals方法

反编译示例代码,发现编译器确实为record类型生成了虚拟的Equals方法:

public virtual bool Equals(A other){  return this == other || (other != null && this.EqualityContract == other.EqualityContract && EqualityComparer<int[]>.Default.Equals(this.<ids>k__BackingField, other.<ids>k__BackingField));}

但是,如果手写override方法,编译报错

如果不加override,编译也报错:

但是,根据“​​必须允许替代​​”这个错误提示,我们加上了virtual方法,居然成功了:

public record B(int[] ids){  public virtual bool Equals(B b)  {    if (b is null) return false;    return ids.SequenceEqual(b.ids);  }}

而且反编译示例代码,发现编译器没有再为record类型自动生成虚拟的Equals方法。

三、结论

如果要为record类型自定义Equals方法,必须定义virtual方法。