比较来自相同类型的两个对象

时间:2014-12-10 19:02:46

标签: c# .net

我正在尝试获取所有已修改的字段,比较同一类型的两个对象。

例如:

public class Order
{
   public int OrderNumber {get;set;}
   public DateTime OrderDate {get;set};
   public string Something {get;set};
}

然后,我保存了一个新订单:

Order order1 = new Order;
order1.OrderNumber = 1;
order1.OrderDate = DateTime.Now;
order1.Something = string.Empty;

Save(order1)

之后,有人试图从这个订单中更改一些信息,我试图找到最好的方法来获取所有已更改的字段并保存到日志中。

这必须适用于任何类型的两个对象;

应该是像

这样的方法
public something ReturnFields(TObject objectSaved, TObject objectChanged)

任何人都可以帮助我吗?

2 个答案:

答案 0 :(得分:0)

如果你使用像txt这样的日志,你可以让你的函数返回一个字符串,如下所示:

public string ReturnFields(TObject objectSaved, TObject objectChanged)
{

    var sb = new StringBuilder();

   if(!objectSaved.Name.Equals(objectChanged.Name)
   {

     sb.Append("Name was changed from " + objectSaved.Name  +" to: " + objectChanged.Name)

   }

   if(!objectSaved.OrderDate.Equals(objectChanged.OrderDate)
   {

   sb.Append("The date whas changed from " + objectSaved.OrderDate+" to: " + objectChanged.OrderDate)

   }

    return sb.ToString();
}

这只是一个简单的方法,你可以阅读一些Linq表达式来做到这一点。

答案 1 :(得分:0)

您可以使用反射来获取对象的属性,并构建一系列表达式来比较每个属性。这样你就可以执行它们,对于那些不相等的人,可以将它们的名字返回给调用者。

如果属性类型本身不是示例中的所有值类型,则需要扩展,否则它只会检查引用相等性。

public static class PropertyCompare<T>
{
    public readonly static Func<T, T, List<string>> ChangedProps;

    private class PropertyComparer<T>
    {
        public Func<T, T, bool> Compare { get; set; }
        public string PropertyName { get; set; }
    }

    static PropertyCompare()
    {
        PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public);
        var firstObject = Expression.Parameter(typeof(T), "a");
        var secondObject = Expression.Parameter(typeof(T), "b");
        PropertyComparer<T>[] propertyComparers = new PropertyComparer<T>[properties.Length];

        for (int i = 0; i < properties.Length; i++) 
        {                        
            PropertyInfo thisProperty = properties[i];
            Expression arePropertiesEqual = Expression.Equal(Expression.Property(firstObject, thisProperty), Expression.Property(secondObject, thisProperty));
            Expression<Func<T, T, bool>> equalityFunc = Expression.Lambda<Func<T, T, bool>>(arePropertiesEqual, firstObject, secondObject);

            PropertyComparer<T> comparer = new PropertyComparer<T>()
            {
                Compare = equalityFunc.Compile(),
                PropertyName = properties[i].Name
            };

            propertyComparers[i] = comparer;                        
        }

        ChangedProps = new Func<T,T,List<string>>((a,b) =>
        {
            List<string> changedFields = new List<string>();

            foreach (PropertyComparer<T> comparer in propertyComparers)
            {
                if (comparer.Compare(a, b))
                    continue;
                changedFields.Add(comparer.PropertyName);
            }

            return changedFields;
        });
    }
}      

public class Order
{
   public int OrderNumber {get;set;}
   public DateTime OrderDate {get;set; }
   public string Something {get; set; }
}

static void Main(string[] args)
{
    Order myOrder1 = new Order() { OrderDate = DateTime.Today, OrderNumber = 1, Something = "bleh" };
    Order myOrder2 = new Order() { OrderDate = DateTime.Today.AddDays(1), OrderNumber = 1, Something = "bleh" };
    List<string> changedFields = PropertyCompare<Order>.ChangedProps(myOrder1, myOrder2);

    Console.ReadKey();
}