You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# record类中自定义EqualityContract属性的正确用法与意图

C# Record中自定义EqualityContract属性的正确用法与预期用途

默认情况下,Record类R的合成System.Type EqualityContract { get; }属性会返回typeof(R),这使得R的实例只能与同类型实例判定相等,不同类型直接返回false,常规场景下这是合理的。但C#允许我们自定义这个属性的实现,这说明它一定有适用场景——比如让多个Record类共享相等契约(比如属性完全一致,或派生自同一基Record),但这里存在矛盾:要实现这种场景需要重写bool Equals(object? other)和bool Equals(Base? other),但C#明确禁止在Record中自定义重写这些Equals方法。

注:本文聚焦于自定义相等契约的目的与可用性,下方示例仅展示一种无法生效的潜在用法,并非探讨其他替代实现方案。

比如想让派生Record类Derived复用基类Base的相等契约,从而允许基于Base的实例属性来比较Base和Derived实例,直觉上会写出这样的代码:

record Base(int X);

record Derived(int X) : Base(X) {
    protected override System.Type EqualityContract => base.EqualityContract;
    public virtual bool Equals(Derived? other) => base.Equals(other);
    public sealed override bool Equals(Base? other) => base.Equals(other); // 编译器禁止
    public override bool Equals(object? other) => base.Equals(other);      // 编译器禁止
    /* 其他额外代码 */
}

但这段代码无法通过编译,因为C#禁止在Record中自定义重写Equals方法。移除这些被禁止的重写后,编译器会为Derived合成如下Equals实现(仅作说明):

record Derived(int X) : Base(X) {
    protected override System.Type EqualityContract => base.EqualityContract;
    public virtual bool Equals(Derived? other) => base.Equals(other);
    public sealed override bool Equals(Base? other) => Equals((object)other); // 合成代码
    public override bool Equals(object? other) => Equals(other as Derived);   // 合成代码
    /* 其他额外代码 */
}

此时相等契约无法正常工作,运行以下代码会输出True False:

Base obj1 = new Base(1);
Derived obj2 = new Derived(1);
System.Console.WriteLine($"{obj1 == obj2} {obj2 == obj1}");

问题分析

两次比较本质上都调用Base的==运算符,该运算符会调用bool Equals(Base? other)方法:

  • obj1 == obj2使用Base的实现:先比较相等契约(此处Derived返回的是Base的类型,所以契约一致),再比较X的值,最终返回true。
  • obj2 == obj1使用Derived合成的Equals(Base? other)实现:该方法会调用Equals((object)other),也就是Derived的object重载Equals,而这个方法会把obj1转换成Derived类型(转换结果为null),因此返回false。

核心疑问

那么,自定义EqualityContract的正确姿势到底是什么?是不是我漏掉了什么关键细节?另外,C#为什么要禁止在Record中自定义重写Equals方法?

我查阅了C#语言设计相关的讨论,其中有两条评论提到上述场景本应可以正常工作,但目前的实现却存在问题。

内容的提问来源于stack exchange,提问作者Bartosz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 12:45:38