Necesito crear un método genérico, que tomará dos objetos (del mismo tipo) y devolverá una lista de propiedades que tienen valores diferentes. Como mi requisito es un poco diferente, no creo que esto sea un duplicado.
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);
El código explica el requisito:
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; }
Debe considerar lo siguiente:
¿Hay bibliotecas disponibles listas para usar allí?
¿Puedo lograr esto usando AutoMapper ?
Mejoré un poco la respuesta de Krishna :
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"); } }
porque no me estaba funcionando. Este lo hace y lo único que necesita para que funcione es el método de extensión IsSimpleType () que adapté de esta respuesta aquí (solo lo convertí en un método de extensión).
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)); }
Prueba esto. debe ser genérico para cualquier clase.
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(); } }
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; } } }