正如标题所说:我是否需要覆盖==
运算符? .Equals()
方法怎么样?我缺少什么?
答案 0 :(得分:80)
msdn
的一个例子public struct Complex
{
double re, im;
public override bool Equals(Object obj)
{
return obj is Complex && this == (Complex)obj;
}
public override int GetHashCode()
{
return re.GetHashCode() ^ im.GetHashCode();
}
public static bool operator ==(Complex x, Complex y)
{
return x.re == y.re && x.im == y.im;
}
public static bool operator !=(Complex x, Complex y)
{
return !(x == y);
}
}
答案 1 :(得分:43)
您还应该实现IEquatable< T>。以下是框架设计指南的摘录:
在值类型上实现IEquatable。 值类型的Object.Equals方法导致装箱,以及它 默认实现效率不高,因为它使用了反射。 IEquatable.Equals可以提供更好的性能 实施,以免它导致拳击。
public struct Int32 : IEquatable<Int32> {
public bool Equals(Int32 other){ ... }
}
请遵循相同的指导原则 覆盖Object.Equals时 实现IEquatable.Equals。 有关详细信息,请参见第8.7.1节 重写Object.Equals的指南
答案 2 :(得分:14)
不幸的是,我没有足够的声誉评论其他参赛作品。所以我在这里发布了对顶级解决方案的可能增强。
纠正我,如果我错了,但上面提到的实施
public struct Complex
{
double re, im;
public override bool Equals(Object obj)
{
return obj is Complex && this == (Complex)obj;
}
public override int GetHashCode()
{
return re.GetHashCode() ^ im.GetHashCode();
}
public static bool operator ==(Complex x, Complex y)
{
return x.re == y.re && x.im == y.im;
}
public static bool operator !=(Complex x, Complex y)
{
return !(x == y);
}
}
有重大缺陷。我在提到
public override int GetHashCode()
{
return re.GetHashCode() ^ im.GetHashCode();
}
XORing是对称的,因此Complex(2,1)和Complex(1,2)会给出相同的hashCode。
我们应该做更像的事情:
public override int GetHashCode()
{
return re.GetHashCode() * 17 ^ im.GetHashCode();
}
答案 3 :(得分:9)
大多数情况下,您可以避免在结构中实现Equals和GetHashcode - 因为编译器会使用按位内容+反射为参考成员自动实现Value类型。
看一下那篇文章: Which is best for data store Struct/Classes?
因此,为了便于使用,您仍然可以实现==和!=。
但大部分时间你都可以避免实现Equals和GetHashcode
您必须实现Equals和GetHashCode的情况适用于您不想考虑的字段。
例如,一个随时间变化的字段,如人的年龄或汽车的instantSpeed(如果你想在同一个地方的字典中找到它,对象的身份不应该改变)
问候,最好的代码
答案 4 :(得分:3)
两者之间的基本区别在于==
运算符是静态的,即在编译时确定调用的适当方法,而在实例上以动态方式调用Equals
方法。 />
定义两者可能是最好的事情,即使在结构的情况下这个问题更少,因为结构不能被扩展(结构不能从另一个继承)。
答案 5 :(得分:0)
为了完整性,我还建议重载initialization
方法:
zc.recipe.egg
这是一个真正的改进,因为Equals
方法
使用值类型的一些最佳做法:
这来自这篇文章:http://theburningmonk.com/2015/07/beware-of-implicit-boxing-of-value-types/