比较Object类的Class属性

时间:2014-07-24 23:38:31

标签: c#

我正在尝试记录对象的每个属性的历史记录,只有在它已经更改后才更新。我没有为每个属性做一个if语句,而是决定遍历我定义了一个自定义属性的每个属性来过滤掉我不想记录的属性,然后比较旧值和新值以查看是否他们已经改变了。

然而,检查每个obj情况是否相等似乎很大且非常具体,因为我还有要比较的枚举类型。有没有更好的方法来完成这个或重构我的代码?

代码示例

MyClass的

public class MyClassDto
{
        [Comparible]
        public MyCustomType CustomType{ get; set; }

        [Comparible]
        public DateTime? SomeDate { get; set; }

        [Comparible]
        public decimal? SomeDecimalValue { get; set; }

        [Comparible]
        public int? SomeIntValue { get; set; }

       // Other Non Custom Attribute Type Properties
}

添加历史记录助手功能

public void AddHistory(MyClassDto prevMyObject, MyClassDto newMyObject)
{
      if (prevMyObject== null || newMyObject == null) return;

      foreach (var property in prevMyObject.GetType().GetProperties().Where(prop => Attribute.IsDefined(prop, typeof (ComparibleAttribute))))
      {
          var fieldName = property.Name;
          object prevValue = property.GetValue(prevMyObject, null);
          object newValue = newMyObject.GetType().GetProperty(property.Name).GetValue(newMyObject, null);

           if (!IsEqual(prevValue, newValue))
           {
               //Log the field, prevValue, newValue
           }
       }
  }

对象比较功能

   private static bool IsEqual(object obj1, object obj2)
    {
        if (obj1 == null && obj2 == null || obj1 == obj2) return true;
        if (obj1 == null || obj2 == null) return false;

        var objType = obj1.GetType();
        if (objType == typeof (string))
        {
            return string.Equals(obj1.ToString(), obj2.ToString());
        }
        if (objType == typeof (int?))
        {
            return (Convert.ToInt32(obj1) == Convert.ToInt32(obj2));
        }
        if (objType == typeof (decimal?) || objType == typeof (decimal))
        {
            return (decimal.Round(Convert.ToDecimal(obj1), 2) == decimal.Round(Convert.ToDecimal(obj2), 2));
        }
        if (objType == typeof (DateTime?) || objType == typeof (DateTime))
        {
            return (Convert.ToDateTime(obj1) == Convert.ToDateTime(obj2));
        }
        if (objType == typeof (ContractTrackerType))
        {
            return (((MyCustomType) obj1).Name() == ((MyCustomType ) obj2).Name());
        }

        return false;
    }

1 个答案:

答案 0 :(得分:1)

您实际上并不需要原始类型的单独案例。对于您的自定义类型,您应该覆盖object.Equals,以便将相等测试逻辑封装在类中。

这样,您的IsEqual功能只需拨打object.Equals

即可
 private static bool IsEqual(object obj1, object obj2)
 {
     return object.Equals(obj1, obj2);
 }

来自object.Equals的说明:

  

静态Equals(Object,Object)方法指示两个对象objA和objB是否相等。它还使您能够测试值为null的对象是否相等。它将objA和objB的相等性进行比较如下:

     

确定两个对象是否表示相同的对象引用。如果是,则该方法返回true。此测试等同于调用ReferenceEquals方法。此外,如果objA和objB都为null,则该方法返回true。

     

确定objA或objB是否为空。如果是,则返回false。

     

如果两个对象不表示相同的对象引用且都不为null,则调用objA.Equals(objB)并返回结果。这意味着如果objA重写了Object.Equals(Object)方法,则会调用此覆盖。