前言
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方法。
想了解更多内容,请关注我的个人公众号”My IO“