关于c#:为接口重载operator ==

Overloading operator== for an interface

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Can I overload an == operator on an Interface?

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

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

正如您可能已经猜到的,我希望实现IFoo的类的行为类似于值类型(至少在比较是否相等时如此)。如你所见,当Assert发生时,foo1foo2的具体类型Foo不再"已知"。所有已知的都是它们的接口IFoo

当然,我可以用IEquatable来写foo1.Equals(foo2),但这不是重点。如果IFoo是抽象的基类而不是接口,我就可以重载operator==没有问题。那么,如何对接口执行相同的操作呢?

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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派生。这决不是对调用方或实现方有约束力的承诺,但它是对两者的提示。


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

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