可能的重复:
比较引用类型的两个实例的"最佳实践"是什么?
我的应用程序有这个自定义类。这个类有两个实例(A 和 B),我试图比较它们。但是,我遇到了问题;我正在使用重写的Equals
方法实现IEquatable<T>
接口来执行此比较。
Equals
方法调用行为不端的ReferenceEquals
函数。
以下是测试用例:
情况1:A和B是不同的实例,包含不同的数据。ReferenceEquals
说:它们是不同的(这是正确的!
情况 2:A 和 B 是不同的实例,但 B 是使用 A 的变量值实例化的(即 A 和 B 都包含完全相同的数据!ReferenceEquals
说:它们是不同的(这是错误的!
情况 3:A 和 B 是相同的实例(即 A 被传入两次,例如Equals (A, A)
)ReferenceEquals
说:它们是相同的(这是正确的!
那么我如何让案例 2 的结果也正确呢?
实现IEquatable<T>
的类:
namespace DBtestApp1
{
class QuantityBasedDiscount : IEquatable<QuantityBasedDiscount>
{
public string pType { get; set; }
public string pSubType { get; set; }
public DataTable quantityDiscountsDT { get; set; }
public QuantityBasedDiscount()
{
pType = "";
pSubType = "";
quantityDiscountsDT = new DataTable();
}
public QuantityBasedDiscount(string iProdType, string iProdSubType, DataTable iQuantitiesDT)
{
pType = iProdType;
pSubType = iProdSubType;
quantityDiscountsDT = iQuantitiesDT;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public override bool Equals(Object obj)
{
var other = obj as QuantityBasedDiscount;
if (other == null) return false;
return Equals(other);
}
public bool Equals(QuantityBasedDiscount other)
{
if (other == null)
{
return false;
}
if (ReferenceEquals(this, other))
{
return true;
}
return false;
}
}
}
调用Equals
方法的代码(此处为案例 2 配置):
private bool AnyUnsavedChanges()
{
QuantityBasedDiscount copyB = new QuantityBasedDiscount(copyA.pType, copyA.pSubType, copyA.quantityDiscountsDT);
if (copyA.Equals(copyB))
{
return false; //They are the same!
}
else
{
return true; //They are NOT the same!
}
}
那么这段代码有什么问题呢?
虽然不是完全相同的重复,但这里有所有答案: 什么是比较引用类型的两个实例的"最佳实践"?.从该线程中获取提供康拉德答案的片段,以永远不会出错。
简而言之,你做错了。您没有比较泛型Equals
方法中的实际值。此外,在Equals
方法中调用==
运算符是不安全的。这样做:
public override int GetHashCode()
{
return pType.GetHashCode() ^ pSubType.GetHashCode() ^ quantityDiscountsDT.GetHashCode();
//or something similar, but fast.
}
public bool Equals(QuantityBasedDiscount other)
{
if (ReferenceEquals(null, other))
{
return false;
}
if (ReferenceEquals(this, other))
{
return true;
}
return pType == other.pType && pSubType == other.pSubType &&
quantityDiscountsDT == other.quantityDiscountsDT;
}
如果修改了数据表字段,这可能仍会给您带来不一致的结果。所有这些都取决于如何为数据表实现==
运算符。为了更好地控制它,您必须派生自己的数据表。
此外,您可能还希望重载==
和!=
运算符。对于所有这些,请检查提供的链接。
你必须覆盖Equals和GetHashCode,如果你喜欢/需要语法,你还需要重载'=='和'!='运算符。在重写 Equals 时,您可以首先检查 ReferenceEquals 是否返回 true,如果没有,则比较对象的内容。
就个人而言,我更喜欢避免在这种情况下使用ReferenceEquals。