说明:
Equals()
比较两个对象的值。ReferenceEquals()
比较他们的参考资料。对于引用类型operator==
默认情况下比较引用,而对于值类型,它使用反射执行(AFAIK)等效的Equals()。
因此。我有一种情况,我需要通过它们的值比较两个引用类型。我可以明确地调用Equals()
或者我可以重载operator==
来执行所需的比较。
然而,重载operator==
进行价值比较有点违反了最不惊讶的原则。另一方面,显式调用双对象Equals
看起来有点矫枉过正。
这里的标准做法是什么?
我知道如何覆盖Equals()
。问题是,覆盖operator==
以测试引用类型上的值相等是否通常是可以接受的,或者是否通常接受的做法是显式调用Equals / ReferenceEquals明确指定你想要的比较。
答案 0 :(得分:3)
什么是标准做法?
&#34;标准做法&#34;是,如果要检查两个元素是否相等而不是引用相等,则需要实现IEquatable<T>
,它引入Equals(T other)
方法,并覆盖GetHashCode
。这样,就可以控制这两个对象的比较方式。通常,这包括覆盖==
和!=
运算符。
而对于值类型,它使用相当于Equals()的(AFAIK)执行 反射。
仅当您的值类型具有作为引用类型的成员时。如果是所有值类型,it will do a bit comparison of these two objects:
// if there are no GC references in this object we can avoid reflection
// and do a fast memcmp
if (CanCompareBits(this))
return FastEqualsCheck(thisObj, obj);
问题是覆盖是否通常是可以接受的 operator ==测试引用类型的值相等性
这实际上取决于你正在做什么。一旦覆盖==
,建议覆盖Equals
运算符,因为您需要一致的行为值相等语义。这取决于您对两个对象之间的相等性的定义。
虽然,如果一个对象是可变的,那么进行值比较可能会导致奇怪的情况,其中两个对象被认为是相等的,但后来有一个是变异的。绝对应该根据每个案例进行分析。通常,覆盖Equals
就足够了。
答案 1 :(得分:2)
P = pic.Problem() Rho = P.add_variable('Rho',(n,n),'hermitian') P.add_constraint(pic.trace(Rho)==1) P.add_constraint(Rho>>0) RhoQOBJ = Qobj(Rho) RhoABtr = ptrace(RhoQOBJ, [0,1]) RhoABqbj = partial_transpose(RhoABtr, [0], method='dense') RhoAB = RhoABqbj.full()
执行两个对象的值比较。
事实并非如此。 Equals()
对值类型的默认行为是使用它们的相等定义来比较每个字段,引用类型的默认行为是比较它们的引用。可以覆盖它做任何你想做的事情。在这方面,它与object.Equals
运算符完全相同。
==
运算符和==
之间的唯一区别是Equals
将在第一个(但不是第二个)操作数上执行虚拟调度,找到基于该方法的实现在该对象的运行时类型上。 Equals
运算符完全静态绑定;它只考虑两个操作数的编译时类型。除了这种绑定差异之外,它们都具有相同的默认行为,并且可以覆盖它们以提供您想要的任何实现。
标准做法是始终确保==
和Equals
的行为与您的类型相同。如果重写operator ==
方法来更改相等语义,那么您还应该重载Equals
运算符以提供*相同的语义`,反之亦然。
答案 2 :(得分:1)
问题是覆盖是否通常是可以接受的 operator ==测试值相等
它取决于对象,如果对象是不可变的,那么你可以覆盖==
运算符,否则不会。 (请记住它们只是指导方针)。
请参阅:Guidelines for Overriding Equals() and Operator == (C# Programming Guide)
默认情况下,运算符==测试引用相等性 确定两个引用是否表示相同的对象。 因此,引用类型不必实现operator == in 为了获得这个功能。 当一个类型是不可变的时,那个 是,实例中包含的数据无法更改, 重载operator ==比较值相等而不是引用相等可能很有用因为,作为不可变对象,它们 只要具有相同的值,就可以认为是相同的。的它 在非不可变类型中覆盖operator ==不是一个好主意。
答案 3 :(得分:0)
为您的代码赋予语义含义是一种很好的做法。因此,如果您应该关注参考比较,请使用类的默认行为;否则应使用应用程序上下文相关逻辑进行比较。 (具有Equals
,GetHashCode
和运算符等所有平等成员的一致行为