除了覆盖Object.Equals()
你应该实现IEquatable<T>
,T
你的类型本身在哪里。 IEquatable<T>.Equals()
接受类型的参数T
。
如果您隐式实现接口(为什么不实现?),那么T
将尽可能使用接受 -typed 参数的更具体的方法,在这种情况下不会发生装箱。(如果您重载Equals()
并且不实现接口,这是正确的,但在这种情况下没有理由不实现接口。)
这是我在实现值类型相等时通常使用的模式:
struct Foo : IEquatable<Foo>
{
public bool Equals(Foo other)
{
// Do your equality test here.
throw new NotImplementedException();
}
public override bool Equals(object other)
{
if (other != null && other is Foo) {
return Equals((Foo)other);
}
return false;
}
// If you also want to overload the equality operator:
public static bool operator==(Foo a, Foo b)
{
return a.Equals(b);
}
public static bool operator!=(Foo a, Foo b)
{
return !a.Equals(b);
}
}
当然,也不要忘记覆盖Object.GetHashCode()
。
请注意,使用该Equals(object)
方法时,只有参数被装箱。您正在调用的对象不会被装箱,除非您object
先将其转换为(或接口类型)。ldloca
将为您调用的对象发出、ldflda
或指令之一ldsflda
(视情况而定),而另一个将被装箱(在没有更具体的重载的情况下)。