C # Compare two objects for properties with different values

I need to create a general method that will take two objects (of the same type) and return a list of properties that have different values. Since my requirement is a little different, I don't think it's like a duplicate.

public class Person
{
   public string Name {get;set;}
   public string Age {get;set;}
}

Person p1 = new Person{FirstName = "David", Age = 33}
Person p2 = new Person{FirstName = "David", Age = 44}

var changedProperties = GetChangedProperties(p1,p2);

The code explains the requirement:

public List<string> GetChangedProperties(object A, object B)
{
    List<string> changedProperties = new List<string>();
   //Compare for changed values in properties 
   if(A.Age != B.Age)
   {
       //changedProperties.Add("Age");
   } 
   //Compare other properties
   ..
   ..
   return changedProperties;
}

The following should be considered:

  • General - should be able to compare objects of any type (with the same class)
  • Performance
  • Plain

Are there any libraries out of the box?

Can I achieve this using AutoMapper ?

+4
source share
4 answers

:

public List<string> GetChangedProperties<T>(object A, object B)
{
    if (A != null && B != null)
    {
        var type = typeof(T);
        var allProperties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
        var allSimpleProperties = allProperties.Where(pi => pi.PropertyType.IsSimpleType());
        var unequalProperties =
               from pi in allSimpleProperties
               let AValue = type.GetProperty(pi.Name).GetValue(A, null)
               let BValue = type.GetProperty(pi.Name).GetValue(B, null)
               where AValue != BValue && (AValue == null || !AValue.Equals(BValue))
               select pi.Name;
        return unequalProperties.ToList();
    }
    else
    {
        throw new ArgumentNullException("You need to provide 2 non-null objects");
    }
}

. , , , IsSimpleType() - Extension, ( ).

public static bool IsSimpleType(this Type type)
{
    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
    {
        // nullable type, check if the nested type is simple.
        return type.GetGenericArguments()[0].IsSimpleType();
    }
    return type.IsPrimitive
      || type.IsEnum
      || type.Equals(typeof(string))
      || type.Equals(typeof(decimal));
}
+2
using System;
using System.Collections.Generic;
using System.Reflection;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            Person p1 = new Person("David", 33);
            Person p2 = new Person("David", 44);

            var changedProperties = GetChangedProperties(p1, p2);
        }

        public class Person
        {
            public Person(string name, int age)
            {
                this.name = name;
                this.age = age;
            }

            public int age { get; set; }
            public string name { get; set; }
        }

        public static List<string> GetChangedProperties(Object A, Object B)
        {
            if (A.GetType() != B.GetType())
            {
                throw new System.InvalidOperationException("Objects of different Type");
            }
            List<string> changedProperties = ElaborateChangedProperties(A.GetType().GetProperties(), B.GetType().GetProperties(), A, B);
            return changedProperties;
        }


        public static List<string> ElaborateChangedProperties(PropertyInfo[] pA, PropertyInfo[] pB, Object A, Object B)
        {
            List<string> changedProperties = new List<string>();
            foreach (PropertyInfo info in pA)
            {
                object propValueA = info.GetValue(A, null);
                object propValueB = info.GetValue(B, null);
                if (propValueA != propValueB)
                {
                    changedProperties.Add(info.Name);
                }
            }
            return changedProperties;
        }
    }
}
+1

. .

 public List<string> GetChangedProperties(object A, object B)
    {
       if (A!= null && B != null)
        {
            var type = typeof(T);
         var unequalProperties =
                from pi in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                where pi.GetUnderlyingType().IsSimpleType() && pi.GetIndexParameters().Length == 0
                let AValue = type.GetProperty(pi.Name).GetValue(A, null)
                let BValue = type.GetProperty(pi.Name).GetValue(B, null)
                where AValue != BValue && (AValue == null || !AValue.Equals(BValue))
                select pi.Name;
     return unequalProperties.ToList();
         }
    }
+1

, . , . , , - , .

public List<string> GetChangedProperties<T>(T a, T b) where T:class
{   
    if (a != null && b != null)
    {
        if (object.Equals(a, b))
        {
            return new List<string>();
        }
        var allProperties = a.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
        return allProperties.Where(p => !object.Equals( p.GetValue(a),p.GetValue(b))).Select(p => p.Name).ToList();
    }
    else
    {
        var aText = $"{(a == null ? ("\"" + nameof(a) + "\"" + " was null") : "")}";
        var bText = $"{(b == null ? ("\"" + nameof(b) + "\"" + " was null") : "")}";
        var bothNull = !string.IsNullOrEmpty(aText) && !string.IsNullOrEmpty(bText);
        throw new ArgumentNullException(aText + (bothNull ? ", ":"" )+ bText );
    }
}
0

Source: https://habr.com/ru/post/1672351/


All Articles