为record类型自定义Equals方法

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为record类型自定义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方法。

想了解更多内容,请关注我的个人公众号”My IO“

以上是关于为record类型自定义Equals方法的主要内容,如果未能解决你的问题,请参考以下文章

Java:自定义实现equals()方法

8.2.3 覆写 Equals

Object-异常声明及捕获-自定义异常

Arraylist中contains方法底层实现解读与HashSet自定义类型去重效果的简述(接上一篇)

C#9引入的自定义类型record

字符串类中的Object的equals方法和自定义类中的Object的equal方法之间有什么区别