【问题标题】:C# with object types the method Object.Equals (object a, object b) returns the wrong result [duplicate]具有对象类型的 C# 方法 Object.Equals (object a, object b) 返回错误的结果 [重复]
【发布时间】:2020-09-01 13:34:38
【问题描述】:

我需要检查对象(不是所有属性),对于原始类型,一切正常,但对于对象类型,方法 Object.Equals(object a, object b) 返回错误的结果。

        public static bool IsModified<T>(T newProp, T oldProp) where T : class
    {
        List<string> IgnoreProps = new List<string> { "UpdatedOn", "UpdatedById", "UpdatedBy", "RowVersion" };

        Type type = typeof(T);
        foreach(PropertyInfo prop in type.GetProperties())
        {
            if (IgnoreProps.Contains(prop.Name))
            {
                continue;
            }

            var propType = prop.PropertyType;

            var newValue = prop.GetValue(newProp);
            var oldValue = prop.GetValue(oldProp);

            newValue = Convert.ChangeType(newValue, propType);
            oldValue = Convert.ChangeType(oldValue, propType);

            var a = Equals(newValue, oldValue); // return incorrect value

            if (!Equals(newValue, oldValue))
            {
                return true;
            }
        }

        return false;
    }

第一个对象

第二个对象

【问题讨论】:

  • 不要将相关信息作为图像添加到问题中,请将值添加为文本。你的类型是否也覆盖了Equals 方法?

标签: c# object reflection compare system.reflection


【解决方案1】:

Equals 的默认实现支持引用相等 引用类型和值类型的按位相等。参考 相等意味着被比较的对象引用引用 同一个对象。按位相等意味着被比较的对象有 相同的二进制表示。 (https://docs.microsoft.com/en-us/dotnet/api/system.object.equals?redirectedfrom=MSDN&view=netcore-3.1)

由于您有两个不同的引用(var newValuevar oldValue),您会得到false

【讨论】:

    【解决方案2】:

    假设您有一个类 MyCustomClass 和以下示例:

    class MyCustomClass
    {
        public string txt;
    }
    
    static void Main(string[] args)
    {
        MyCustomClass cl1 = new MyCustomClass()
        {
            txt = "a"
        };
        MyCustomClass cl2 = new MyCustomClass()
        {
            txt = "a"
        };
    
        if (Equals(cl1, cl2))
            Console.WriteLine("equal");
        else
            Console.WriteLine("NOT equal");
    }
    

    如果你运行上面的代码,你会得到NOT equal的输出。这是因为 .net 将尝试仅比较该类的 2 个实例之间的引用。例如,如果你写:

        if (Equals(cl1, cl1))
            Console.WriteLine("equal");
        else
            Console.WriteLine("NOT equal");
    

    当您将同一实例 cl1cl1 进行比较时,这将导致 equal

    为了与 Equals 方法进行比较,您必须在类中覆盖它。例如你的班级应该变成:

    class MyCustomClass
    {
        public string txt;
    
        public override bool Equals(object obj)
        {
            //Check for null and compare run-time types.
            if ((obj == null) || !this.GetType().Equals(obj.GetType()))
            {
                return false;
            }
            else
            {
                MyCustomClass p = (MyCustomClass)obj;
                return (txt == p.txt);
            }
        }
    }
    

    上面的Equals方法,不仅保证了比较对象是not null,也保证了same type的对象,而且保证了对它们的所有字段一一比较。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-08
      • 2013-04-19
      • 2012-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多