简体   繁体   English

C# 带有抽象 Equals 方法的抽象记录

[英]C# abstract record with abstract Equals method

Why are we not allowed to do the following for a record为什么我们不允许做以下记录

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
  }
}

while it is totally acceptable for classes?虽然上课完全可以接受?

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

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

By the way, I am doing this implementation to enforce the Equals check to cascade to its derived classes.顺便说一句,我正在执行此实现以强制 Equals 检查级联到其派生类。

Edit: just to give context on why am I interested on this is because I am currently creating an library/autogenerator for IEquatable.编辑:只是为了说明我为什么对此感兴趣,因为我目前正在为 IEquatable 创建一个库/自动生成器。

Edit/Info 2: Based on the comments, I have done some tests.编辑/信息 2:根据评论,我做了一些测试。 since the abstract Equals method of record can't be overridden, I tried leaving it as is.由于无法覆盖抽象的 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; }
}

The result I get an error of System.BadImageFormatException: Bad IL format.结果我得到一个错误System.BadImageFormatException: Bad IL format。

All in all, abstract Equals method on records is not just an unnecessary implementation but is also a bad one.总而言之,记录上的抽象 Equals 方法不仅是一种不必要的实现,而且也是一个糟糕的实现。

This is because compiler already implements equality methods for records.这是因为编译器已经为记录实现了相等方法。 Check Value equality of records:检查记录的值相等性:

To implement value equality, the compiler synthesizes the following methods:为了实现值相等,编译器综合了以下方法:

  • An override of Object.Equals(Object). Object.Equals(Object) 的覆盖。

  • This method is used as the basis for the Object.Equals(Object, Object) static method when both parameters are non-null.当两个参数都为非空时,此方法用作 Object.Equals(Object, Object) static 方法的基础。

  • A virtual Equals method whose parameter is the record type.一个虚拟的 Equals 方法,其参数是记录类型。 This method implements IEquatable.此方法实现 IEquatable。

  • An override of Object.GetHashCode().覆盖 Object.GetHashCode()。

  • Overrides of operators == and.=.运算符 == 和.= 的覆盖。

It means that there's not need to enforce the implementation of Equals method in the base abstract record.这意味着不需要在基本抽象记录中强制执行Equals方法。

If you still want to have custom Equals method implementation and derive from some base record you could do so by declaring virtual Equals method with the derived type as an argument:如果您仍然想要自定义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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM