5

如何比较两个对象的属性以确定是否有任何属性发生了变化?我有一个Patient具有一系列属性的对象。我有第二个对象 ,UpdatedPatient它可能有不同的值。目前,我对每个属性使用以下内容:

if (exPt.Id!= pt.Id)
{
    exPt.Id = pt.Id;
    PatientChanged = true;
}

检查所有属性后,如果PatientChanged标志为true,则更新患者。是的,它有效,但我质疑这是否是最有效的解决方案。

4

3 回答 3

9

是的,它有效,但我质疑这是否是最有效的解决方案。

就运行时效率而言,这可能是最有效的解决方案。

检查所有属性后,如果 PatientChanged 标志为 true,则更新患者

如果您缩短 curcuit,您可以加快速度 - 一旦检查了任何属性并且PatientChangedis true,您知道您需要更新,因此您可以跳过其他检查。

当然,您可以使用Reflection编写一个方法来为您执行此检查。但是,这在性能方面效率会低得多,但它可能会消除为所有类型编写这些检查的必要,这可以提高开发人员的效率。

于 2013-05-30T17:16:32.983 回答
5

我质疑这是否是最有效的解决方案。

答案取决于您衡量效率的方式。

  • 就 CPU 周期而言,这是最有效的方式
  • 在维护工作方面,基于反射的方法将被证明更有效。

您可能希望构建一个混合 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));

这是ideone 上这种方法的演示。

请注意,此实现相当简单。它==用于所有属性,而不是Equals在适当的地方使用。您可以通过使第 7 行更复杂来扩展它。

于 2013-05-30T17:17:38.940 回答
0

如果您将 exPt 设为结构而不是类,则其 .Equals 方法将比较每个字段,而不是参考比较。

于 2013-05-30T17:20:54.857 回答