使用抽象 Equals 方法的 C# 抽象记录

C# abstract record with abstract Equals method

为什么不允许我们做以下记录

abstract record AA
{
  public abstract bool Equals(AA other);
}

record BB:AA
{
  public override bool Equals(AA other)// error as it is already implemented
  {
    //do some thing
  }
}

而 类 完全可以接受?

abstract class AA
{
   public abstract bool Equals(AA other);
}

class BB:AA
{
  public override bool Equals(AA other)
  {
    //do some thing
  }
}

顺便说一句,我正在执行此实现以强制执行等于检查以级联到其派生的 类。

编辑: 只是为了说明我为什么对此感兴趣,因为我目前正在为 IEquatable 创建一个 library/autogenerator

Edit/Info 2: 根据评论,我做了一些测试。由于无法覆盖 record 的抽象 Equals 方法,因此我尝试保持原样。

public abstract record AA
{
    public int Prop1 { get; set; }
    public string? Prop2 { get; set; }
    public string? Prop5 { get; set; }
    public abstract bool Equals(AA? other);
}

public record BB : AA
{
    public string? Prop3 { get; set; }
}

结果我得到一个错误 System.BadImageFormatException: Bad IL format.

总而言之,记录上的抽象 Equals 方法不仅是一个不必要的实现,而且也是一个糟糕的实现。

这是因为编译器已经实现了记录的相等方法。检查 Value equality 条记录:

To implement value equality, the compiler synthesizes the following methods:

  • An override of Object.Equals(Object).

  • This method is used as the basis for the Object.Equals(Object, Object) static method when both parameters are non-null.

  • A virtual Equals method whose parameter is the record type. This method implements IEquatable.

  • An override of Object.GetHashCode().

  • Overrides of operators == and !=.

这意味着不需要在基础抽象记录中强制执行Equals方法。

如果您仍然想要自定义 Equals 方法实现并从一些基本记录派生,您可以通过声明虚拟 Equals 方法并将派生类型作为参数来实现:

abstract record AA
{
    // Redundant in case of records and can be omitted.
    public abstract bool Equals(AA other);
}

record BB : AA
{
    public virtual bool Equals(BB other)
    {
        throw new NotImplementedException();
    }
}