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

C# 11能否自动实现IEquatable<T>与IComparable<T>?相关疑问

关于C#接口默认实现与值类型运算符样板代码的问题解答

问题1:为何接口virtual默认实现仍需在结构体中手动实现?

需要分两种核心场景解释:

  • 实例方法的默认实现:C#8引入的接口实例默认实现,本质上属于接口类型的成员,而非实现类型的成员。对于Int256这类值类型来说,若不在结构体中手动实现或重写接口方法,直接通过结构体实例调用接口方法会触发装箱操作(将值类型转换为接口引用类型),既带来性能损耗,也不符合值类型的设计初衷。此外,C#编译器不会自动将接口的默认实现“注入”到值类型的实例成员中,因此必须手动实现才能让结构体直接拥有这些方法。
  • 静态运算符的默认实现:==、!=等运算符属于静态成员,即便C#11支持了静态接口方法,接口的静态默认实现也不会自动成为值类型的静态成员。C#的静态成员是类型专属的,接口的静态成员仅属于接口本身,实现类型无法自动继承这些静态成员作为自己的运算符。因此你必须在Int256中手动编写运算符代码,再在其中调用接口的静态默认逻辑,无法直接复用。

举个实际示例,假设你定义了自定义接口:

public interface IAutoEquatable<T> where T : IAutoEquatable<T>
{
    static virtual bool operator ==(T left, T right)
    {
        return left.Equals(right);
    }

    static virtual bool operator !=(T left, T right)
    {
        return !(left == right);
    }

    bool Equals(T? other);
}

当Int256 : IAutoEquatable<Int256>时,编译器不会自动把接口的==运算符转为Int256的运算符,必须手动编写包装代码:

public struct Int256 : IAutoEquatable<Int256>
{
    public bool Equals(Int256? other)
    {
        // 自定义相等逻辑
    }

    // 必须手动实现,否则编译器报错
    public static bool operator ==(Int256 left, Int256 right)
    {
        return IAutoEquatable<Int256>.operator ==(left, right);
    }

    public static bool operator !=(Int256 left, Int256 right)
    {
        return IAutoEquatable<Int256>.operator !=(left, right);
    }
}

问题2:未来C#版本是否会解决该问题?

目前C#已经有现成的简化方案:C#10引入的record struct可以自动实现IEquatable<T>以及==、!=运算符(基于值的逐字段比较),如果你的Int256可以基于逐字段相等判断,直接用record struct就能省去大部分样板代码。

对于自定义逻辑的场景,C#设计团队一直在收集社区需求,后续版本有可能推出更灵活的特性:

  • 支持实现类型自动继承接口的静态默认成员,无需手动编写运算符的包装代码;
  • 增强源生成器能力,让编译器可基于接口标记自动生成所需的运算符和接口方法实现。

另外,现在你也可以通过自定义源生成器解决问题:编写一个源生成器,当检测到结构体实现IAutoEquatable<T>或IAutoComparable<T>时,自动生成对应的运算符和接口方法实现,完全省去手动编写样板代码的工作。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 02:57:43