Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 比较两个自定义类对象时遇到问题_C#_Compare_Equals_Equality_Iequatable - Fatal编程技术网

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

C# 比较两个自定义类对象时遇到问题,c#,compare,equals,equality,iequatable,C#,Compare,Equals,Equality,Iequatable,可能重复: 我有这个自定义类用于我的应用程序。这个类有两个实例(A和B),我正试图比较它们。然而,我有问题;我正在使用重写的Equals方法实现IEquatable接口来进行比较 Equals方法调用ReferenceEquals函数,该函数行为不正常 以下是测试用例: 案例1:A和B是不同的实例,包含不同的数据ReferenceEquals说:它们是不同的(这是正确的!) 案例2:A和B是不同的实例,但B是使用A的变量值实例化的(即A和B都包含完全相同的数据!)ReferenceEquals

可能重复:

我有这个自定义类用于我的应用程序。这个类有两个实例(A和B),我正试图比较它们。然而,我有问题;我正在使用重写的
Equals
方法实现
IEquatable
接口来进行比较

Equals
方法调用
ReferenceEquals
函数,该函数行为不正常

以下是测试用例:

案例1:A和B是不同的实例,包含不同的数据
ReferenceEquals
说:它们是不同的(这是正确的!)

案例2:A和B是不同的实例,但B是使用A的变量值实例化的(即A和B都包含完全相同的数据!)
ReferenceEquals
说:它们是不同的(这是错误的!)

案例3:A和B是相同的实例(即A被传递两次,例如
Equals(A,A)
ReferenceEquals说:它们是相同的(这是正确的!)

那么,如何才能使案例2的结果也正确呢

实现了
IEquatable
的类:

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;
        }
    }
}
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和GetHashCode,如果您喜欢/需要语法,还需要重载“==”和“!=”接线员。在重写Equals中,您可以首先检查ReferenceEquals是否返回true,如果不是,则比较对象的内容


就我个人而言,我宁愿避免在这种情况下使用ReferenceEquals。

虽然不是完全重复的,但您在这里有所有答案:。从该线程中获取康拉德提供的答案片段,以避免出错


简言之,你做错了。您没有在通用的
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


此外,您可能需要重载
==
=运算符。对于所有这些,请检查提供的链接

我不明白案例2。“…包含完全相同的数据。ReferenceEquals表示:它们不同,这是错误的”
ReferenceEquals
确定指定的对象实例是否为同一实例,而不是是否具有相同的值。哦,我明白了。。。对于实例不同但值相同的情况,如何进行这样的比较?我认为ReferenceEquals也可以处理这种情况。@Ahmad:您必须手动处理,将当前对象字段与其他对象字段进行比较。。。这就是重写
Equals(object other)
的目的。单独比较字段将是一项极其困难的任务,我希望以某种方式避免这种情况!我定义的许多其他类也需要这个实例比较功能,它们包含很多字段,这些字段的数据类型是复杂的结构。。。肯定有什么方法可以进行这样的类实例比较吗?@Ahmad:不幸的是,你不能。也许resharper或其他一些工具可以自动创建用于此比较的代码,但是没有内置函数来为类(引用类型)执行此操作。值类型本质上是这样实现的,但不建议将具有多个字段的对象实现为结构。。。