比较Object类型的类属性
本文关键字:属性 类型 Object 比较 | 更新日期: 2023-09-27 18:14:36
我试图记录一个对象的每个属性的历史记录,只有在它已经改变的情况下才更新。而不是为每个属性做一个if语句,我决定循环通过每个属性,我已经定义了一个自定义属性来过滤掉那些我不想记录的,然后比较旧的和新的值,看看他们是否已经改变。
然而,检查每个对象的相等性似乎很大,而且非常具体,因为我也有枚举类型来比较。是否有更好的方法来实现这一点或重构我的代码?
代码范例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;
}
对于基本类型,实际上不需要单独的大小写。对于您的自定义类型,您应该让它们覆盖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。
如果两个对象不代表相同的对象引用,并且都不为空,则调用objA.Equals(objB)并返回结果。这意味着如果objA覆盖了Object. equals (Object)方法,就会调用这个覆盖。