可能重复:
What is “Best Practice” For Comparing Two Instances of a Reference Type?
我的应用程序有这个自定义类。这个类有两个实例(A和B),我试图比较它。但是,我遇到了问题;我正在使用重写的IEquatable<T>
方法实现Equals
接口来进行此比较。
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!
}
}
那么这段代码中的问题是什么?
答案 0 :(得分:2)
虽然不完全重复,但您在此处获得了所有答案:What is "Best Practice" For Comparing Two Instances of a Reference Type?。从该线程获取Konrad提供的答案永远不会出错。
简而言之,你做错了。您没有比较通用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;
}
如果修改了DataTable字段,这可能仍然会给您带来不一致的结果。所有这些都取决于如何为DataTable实现==
运算符。要获得更多控制权,您必须派生自己的DataTable ..
此外,您可能还想重载==
和!=
运算符。对于所有检查提供的链接。
答案 1 :(得分:0)
你必须重写Equals和GetHashCode,如果你需要/需要语法,你还需要重载'=='和'!='运算符。在重写Equals时,您可以先检查ReferenceEquals是否返回true,如果不是,则比较对象的内容。
我个人更喜欢在这种情况下避免使用ReferenceEquals。