【问题标题】:Can I overload an == operator on an Interface?我可以在接口上重载 == 运算符吗?
【发布时间】:2011-02-21 13:02:42
【问题描述】:

我有一个这样的界面:

public interface IFoo
{
  int A {get;}
  int B {get;}
}

我有多个实现 IFoo 的类。
我想检查相等性,而不是基于 ReferenceEquality,但是如果 A 和 B 相同,则两个 IFoo 应该被认为是相等的(实际上我正在检查通过 WCF 发送的键值对的集合,这就是为什么我可以'没有 ReferenceEquality)。
现在如果我有:

IFoo first = new FooBar1() { A = 1, B = 1};
IFoo second = new FooBar2() { A = 1, B = 1};
if (first == second) {
 //this should return true
}

目前IFooIEquatable<IFoo>,所以FooBar1 和FooBar2 会覆盖Equals(IFoo other),但这不是在== 上调用的。我正在寻找我的代码以在任何地方用a.Equals(b) 替换a==b,但这并不好。

我能做什么?

【问题讨论】:

    标签: c# .net interface equality iequatable


    【解决方案1】:

    不,你不能。重载== 需要您使用的其中一种类型的静态方法,并且接口不能包含这些方法。扩展方法也无济于事。所以在接口上 == 总是使用引用相等。

    请注意,如果 a==null,a.Equals(b) 将引发异常。

    【讨论】:

    • 是的,为此我已经写了一个 EqualsWithNull 扩展,它对 a.EqualsWithNull(b) 返回 true...
    • @TDaver 或者你可以使用Object.Equals(a, b),因为每个类型都继承了 Object,可以缩短为 Equals(a, b)
    【解决方案2】:

    不,您既不能在接口上重载运算符,也不能确保任何实现者都这样做(因为运算符重载在 C# 中是静态的 )。

    你最好的选择就是你所做的,让IFooIEquatable<IFoo>继承并使用Equals(IFoo)

    【讨论】:

      【解决方案3】:

      除了CodeInChaos'的回答你可能有兴趣阅读Guidelines for Overriding Equals() and Operator ==

      【讨论】:

      • 但请注意,当类型不可变时,它表示要重载 operator ==operator !=。所以有接口(多个类型相同的接口但不同的语义都是不可变的)需要使用抽象基而不是接口,所以当其他类型返回混合集合时我可以覆盖运算符。最后:达到 CLR 类型系统的极限(再次:-( )。
      【解决方案4】:

      自从引入 C# 8 以来,您可以为接口提供默认实现和静态方法(允许您为接口定义运算符)

      更多: https://docs.microsoft.com/dotnet/csharp/tutorials/default-interface-methods-versions

      【讨论】:

        【解决方案5】:

        你在这里谈论的是一个实现细节,一个接口不应该(不能)定义它是如何实现的。

        【讨论】:

        • 你没有错,但你的答案更接近评论。这不是一个“为什么”的问题。 (只是猜测,我没有投票。)
        猜你喜欢
        • 2011-04-06
        • 1970-01-01
        • 1970-01-01
        • 2021-10-22
        • 1970-01-01
        • 1970-01-01
        • 2011-11-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多