重载接口的运算符==

本文关键字:运算符 接口 重载 | 更新日期: 2023-09-27 18:29:02

可能重复:
我可以在接口上重载==运算符吗?

我确实理解如何为单个类重载operator==。我甚至让它与遗产一起工作。但我似乎无法将其实现为接口。想象一下:

IFoo foo1 = new Foo(42);
IFoo foo2 = new Foo(42);
Assert.IsTrue( foo1 == foo2 ); // fails

正如您可能已经猜到的那样,我希望实现IFoo的类表现得像一个值类型(至少在比较相等性时)。正如您所看到的,当Assert发生时,foo1foo2的具体类型Foo不再"已知"。所有已知的是它们的接口IFoo

当然,我可以使用IEquatable<IFoo>并编写foo1.Equals(foo2),但这不是重点。如果IFoo是一个抽象基类而不是一个接口,我可以重载operator==,这没有问题那么我该如何对接口执行同样的操作呢

这个问题基本上可以归结为无法写入以下内容,因为leftright中至少有一个必须是Foo:

public interface IFoo : IEquatable<IFoo>
{
  int Id { get; }
}
public class Foo : IFoo
{
  public int Id { get; private set; }
  ... // some implementation here
  public static bool operator== ( IFoo left, IFoo right ) // impossible
  {
    ... // some null checks here
    return left.Id == right.Id;
  }
}

为接口重载operator==是不可能的,还是我错过了一个技巧?

重载接口的运算符==

不可能在接口上重载运算符。重载运算符的核心基本上是编译器将运算符映射到的静态方法。这意味着重载运算符具有与接口中的静态方法相同的问题,因此被禁止。

指定接口具有非引用相等语义的最佳方法是让它从IEquatable<T>派生。这绝不是对调用者或实现者的绑定承诺,而是对两者的提示。

您可以在界面中定义bool Equals(Object)而不是运算符,并使用Object.Equals(Object, Object)进行比较。

这种比较是在类级别上进行的,而不是在接口级别上,并且在比较中还可能涉及类的其他属性。如果您希望对两个接口进行纯粹的比较(比较属性),那么您必须定义自己的静态方法来实现这一点。