为接口重载operator==

4

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

我知道如何为单个类重载operator==。我甚至使它适用于继承。但是我似乎无法为一个接口实现它。想象一下以下情况:

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

正如你所猜测的那样,我希望实现IFoo的类在比较相等性时表现得像值类型。正如你所看到的,当Assert发生时,foo1和foo2的具体类型Foo不再“已知”。所有已知的仅为它们的接口IFoo。
当然,我可以使用IEquatable并编写foo1.Equals(foo2)来代替,但这不是重点。如果IFoo是抽象基类而不是接口,我可以轻松地重载operator==。那么我该如何处理接口呢?
问题基本上归结为无法编写以下内容,因为left和right中至少有一个必须是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==是否不可能,还是我错过了什么技巧?


请不要在标题中加入C#,这就是标签的用途。 - Justin Pihony
2个回答

4

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

指定接口具有非引用相等语义的最佳方法是使其派生自IEquatable<T>。这绝不是对调用方或实现者的强制性承诺,但对两者都是一个提示。


很遗憾这不被支持,使用基类代替也不是一个选项。至少有一点点 工具支持,可以查找使用 operator== 而非 .Equals 的用例。 - Jonas Bötel

1
你可以在接口中定义bool Equals(Object),而不是运算符,并使用Object.Equals(Object, Object)进行比较。
这种比较是在类级别上进行的,而不是在接口级别上进行的,也可能涉及类的其他属性。如果你希望纯粹比较两个接口(比较属性),那么你必须定义自己的静态方法来实现这一点。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接