如何高效的比较两个 Object 对象是否相等?

戎元忠
2023-12-01

咨询区

  • DmitryBoyko

我有两个复杂的对象 Object1Object2,这两个对象大概有 5 层的深度。

我现在需要一个快速的方法比较两个对象是否相等,请问我该如何实现?

回答区

  • vivek nuna

如果你的class是一个不可变的,比如说它下面的属性是那种一创建之后就不会再变更的情况,同时又是 C#9 的话,我建议你使用一个叫 record 的新特性,参考如下代码:

public record Person
{
    public string LastName { get; }
    public string FirstName { get; }

    public Person(string first, string last) => (FirstName, LastName) = (first, last);
}

var person1 = new Person("Bill", "Wagner");
var person2 = new Person("Bill", "Wagner");

Console.WriteLine(person1 == person2); // true
  • Arvo Bowen

可以通过序列化的方式来比较两个 object 是否相等,如果要这么做的话,可以使用扩展方法来实现,参考如下代码:

using System.IO;
using System.Xml.Serialization;

static class ObjectHelpers
{
    public static string SerializeObject<T>(this T toSerialize)
    {
        XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());

        using (StringWriter textWriter = new StringWriter())
        {
            xmlSerializer.Serialize(textWriter, toSerialize);
            return textWriter.ToString();
        }
    }

    public static bool EqualTo(this object obj, object toCompare)
    {
        if (obj.SerializeObject() == toCompare.SerializeObject())
            return true;
        else
            return false;
    }

    public static bool IsBlank<T>(this T obj) where T: new()
    {
        T blank = new T();
        T newObj = ((T)obj);

        if (newObj.SerializeObject() == blank.SerializeObject())
            return true;
        else
            return false;
    }

}

然后像下面这样使用。

if (record.IsBlank())
    throw new Exception("Record found is blank.");

if (record.EqualTo(new record()))
    throw new Exception("Record found is blank.");
  • goric

可以通过反射对类中的所有属性进行比较,参考如下代码:

static bool Compare<T>(T Object1, T object2)
 {
      //Get the type of the object
      Type type = typeof(T);

      //return false if any of the object is false
      if (object.Equals(Object1, default(T)) || object.Equals(object2, default(T)))
         return false;

     //Loop through each properties inside class and get values for the property from both the objects and compare
     foreach (System.Reflection.PropertyInfo property in type.GetProperties())
     {
          if (property.Name != "ExtensionData")
          {
              string Object1Value = string.Empty;
              string Object2Value = string.Empty;
              if (type.GetProperty(property.Name).GetValue(Object1, null) != null)
                    Object1Value = type.GetProperty(property.Name).GetValue(Object1, null).ToString();
              if (type.GetProperty(property.Name).GetValue(object2, null) != null)
                    Object2Value = type.GetProperty(property.Name).GetValue(object2, null).ToString();
              if (Object1Value.Trim() != Object2Value.Trim())
              {
                  return false;
              }
          }
     }
     return true;
 }

点评区

在现实项目开发中,很多时候你无法对 class 进行操控,比如说,不能给它实现个什么 IEquatable<T> 接口,也不能重写它的 Equals()Override() 方法,所以说用 序列化 的方式进行比较还是比较简单粗暴的。

 类似资料: