重载接口的运算符==
本文关键字:运算符 接口 重载 | 更新日期: 2023-09-27 18:29:02
可能重复:
我可以在接口上重载==运算符吗?
我确实理解如何为单个类重载operator==
。我甚至让它与遗产一起工作。但我似乎无法将其实现为接口。想象一下:
IFoo foo1 = new Foo(42);
IFoo foo2 = new Foo(42);
Assert.IsTrue( foo1 == foo2 ); // fails
正如您可能已经猜到的那样,我希望实现IFoo
的类表现得像一个值类型(至少在比较相等性时)。正如您所看到的,当Assert
发生时,foo1
和foo2
的具体类型Foo
不再"已知"。所有已知的是它们的接口IFoo
。
当然,我可以使用IEquatable<IFoo>
并编写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==
是不可能的,还是我错过了一个技巧?
不可能在接口上重载运算符。重载运算符的核心基本上是编译器将运算符映射到的静态方法。这意味着重载运算符具有与接口中的静态方法相同的问题,因此被禁止。
指定接口具有非引用相等语义的最佳方法是让它从IEquatable<T>
派生。这绝不是对调用者或实现者的绑定承诺,而是对两者的提示。
您可以在界面中定义bool Equals(Object)
而不是运算符,并使用Object.Equals(Object, Object)
进行比较。
这种比较是在类级别上进行的,而不是在接口级别上,并且在比较中还可能涉及类的其他属性。如果您希望对两个接口进行纯粹的比较(比较属性),那么您必须定义自己的静态方法来实现这一点。