如何比较两个对象的属性以确定是否有任何属性已更改?我有一个Patient
对象,其中包含一系列属性。我有第二个对象UpdatedPatient
,可能有不同的值。目前,我正在为每个属性使用以下内容:
if (exPt.Id!= pt.Id)
{
exPt.Id = pt.Id;
PatientChanged = true;
}
检查完所有属性后,如果PatientChanged
标记为true
,则会更新患者。是的,它有效,但我在质疑这是否是最有效的解决方案。
答案 0 :(得分:9)
是的,它有效,但我在质疑这是否是最有效的解决方案。
就运行时效率而言,这可能是最有效的解决方案。
检查完所有属性后,如果PatientChanged标志为true,则更新患者
如果您缩短电路,可以加快速度 - 只要选中任何属性且PatientChanged
为true
,您就知道需要更新,所以你可以跳过其他检查。
当然,您可以使用Reflection编写一个方法来为您执行此检查。但是,这在性能方面效率要低得多,但它可能消除了为所有类型编写这些检查,这可以提高开发人员的效率。
答案 1 :(得分:5)
我在质疑这是否是最有效的解决方案。
答案取决于衡量效率的方式。
您可能希望构建一个混合LINQ / Reflection解决方案以获得可接受的效率并保持可维护性:使用反射来获取您需要比较的所有属性,构建一个逐个比较它们的LINQ表达式树,编译它作为一个lambda,并使用结果函子进行CPU效率比较。
以下是混合方法的示例实现:
public static Func<T,T,bool> MakeComparator<T>() {
var lhs = Expression.Parameter(typeof (T));
var rhs = Expression.Parameter(typeof (T));
var allPropChecks = typeof(T)
.GetProperties()
.Where(p => p.CanRead && p.GetIndexParameters().Length == 0)
.Select(p => Expression.Equal(Expression.Property(lhs, p), Expression.Property(rhs, p)))
.ToList();
Expression compare;
if (allPropChecks.Count == 0) {
return (a,b) => true; // Objects with no properties are the same
} else {
compare = allPropChecks[0];
compare = allPropChecks
.Skip(1)
.Aggregate(compare, Expression.AndAlso);
}
return (Func<T, T, bool>)Expression.Lambda(compare, new[] { lhs, rhs }).Compile();
}
使用此方法,您可以执行以下比较:
class Point3D {
public int X { get; set; }
public int Y { get; set; }
public int Z { get; set; }
}
...
// Construct sample objects
var p1 = new Point3D { X = 1, Y = 2, Z = 3};
var p2 = new Point3D { X = 1, Y = 2, Z = 3 };
var p3 = new Point3D { X = 1, Y = 3, Z = 1 };
// Get a comparator
var cmp = MakeComparator<Point3D>();
// Use the comparator to compare objects to each other
Console.WriteLine(cmp(p1, p2));
Console.WriteLine(cmp(p2, p3));
这是demo of this approach on ideone。
请注意,此实现相当简单。它对所有属性使用==
,而不是在适当时使用Equals
。你可以通过使第7行更复杂来扩展它。
答案 2 :(得分:0)
如果你使exPt成为一个结构而不是一个类,那么它的.Equals方法会比较每个字段,而不是参考比较。