c# - 带有抽象 Equals 方法的 C# 抽象记录
问题描述
为什么我们不允许做以下记录
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
}
}
顺便说一句,我正在执行此实现以强制 Equals 检查级联到其派生类。
编辑:只是为了说明我为什么对此感兴趣,因为我目前正在为 IEquatable创建一个库/自动生成器。
编辑/信息 2:根据评论,我做了一些测试。由于无法覆盖抽象的 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 方法不仅是一种不必要的实现,而且也是一个糟糕的实现。
解决方案
这是因为编译器已经为记录实现了相等方法。检查记录的值相等性:
为了实现值相等,编译器综合了以下方法:
Object.Equals(Object) 的覆盖。
当两个参数都不为空时,此方法用作 Object.Equals(Object, Object) 静态方法的基础。
一个虚拟的 Equals 方法,其参数是记录类型。此方法实现 IEquatable。
Object.GetHashCode() 的覆盖。
运算符 == 和 != 的覆盖。
这意味着不需要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();
}
}
推荐阅读
- gradle - Gradle 和 Shadow 插件 - 在 shadowJar 任务之后将附加文件(.jar 文件)复制到最终 jar
- r - R data.table:在复合调用中使用优化的 mean() 函数?
- sass - 使用 SCSS 循环生成嵌套选择器?
- algorithm - 选择在凸包中寻找桥的点
- gridex - Janus Gridex Exporter 至臻完美
- matlab - MATLAB linear least squares with sparse b
- java - 递归调用中的预增量
- apache-spark - 运行 Zeppelin Notebook 时出现 AbstractMethodError
- php - PHP Google Classroom API turnin() TurnInStudentSubmissionRequest
- html - 对齐项目:居中;不适用于截断的菜单