C# 比较同一类型的两个对象

C# 比较同一类型的两个对象,c#,.net,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 =

我试图获取所有修改过的字段,比较同一类型的两个对象

例如:

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)

有人能帮我吗?

如果您使用的是类似于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表达式的内容来进行操作。

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

但是,如果属性类型本身并非如示例中所示的所有值类型,则需要进行扩展,否则它将只执行引用相等性检查

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();
}

您是否知道实体框架可以为您这样做?必须适用于任何类型的两个对象-:您如何定义两个一次读取对象(例如NetworkStream)的相等性?平等是比它看起来更难的话题。侧记:考虑显示一些基本的尝试来实现你的需求-通过反射获得字段列表,并通过调用.to等比逐一进行比较,应该给你一个很好的起点来考虑所有有趣的角落情况。我没有得到这两个对象的一部分。如果有人对这个顺序进行了更改,那么与另一个顺序相比又有什么关系呢?接下来,如果我们讨论的是数量有限的不同对象类型,那么如果对象始终是有序的,那么它就起作用了。但是我在想我的程序中的通用对象谢谢!我创建了一个项目,它工作得很好。我将尝试在我的项目中使用你的想法。谢谢!