比较两个自定义类对象时遇到问题

时间:2012-12-23 15:05:31

标签: c# compare equals equality iequatable

  

可能重复:
  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!
    }

}

那么这段代码中的问题是什么?

2 个答案:

答案 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。