Compare two objects for properties with different values
I improved a little on Krishnas answer:
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");
}
}
because it wasn't working for me. This one does and the only other thing you need to make it work is the IsSimpleType()-Extension Method that I adapted from this answer here (I only converted it into an extension method).
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));
}
Try this. should be generic for any class.
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();
}
}