Reputation: 35223
public static bool PropertiesEqual<T>(T self, T to, params string[] skip)
where T : class
{
if (self != null && to != null)
{
var selfType = self.GetType();
var skipList = new List<string>(skip);
foreach (PropertyInfo pi in selfType.GetProperties(BindingFlags.Public |
BindingFlags.Instance))
{
if (skipList.Contains(pi.Name)) continue;
var selfValue = selfType.GetProperty(pi.Name).GetValue(self, null);
var toValue = selfType.GetProperty(pi.Name).GetValue(to, null);
if (selfValue != toValue && (selfValue == null ||
!selfValue.Equals(toValue)))
{
return false;
}
}
return true;
}
return self == to;
}
I would like to extend my EF entities with an extension method that compares the primitive(?) properties of two instances (properties like numbers, strings, bools and not attached objects).
What I would like to know is, is it possible to make this as an extension method? Or do I need to define this in a POCO class for each EF type that i want to do instance1.PropertiesEqual(instance2)
?
The second thing I would like to know is how to properly target only the data types that I mentioned above, and skip attached objects (connected tables).
Upvotes: 1
Views: 166
Reputation: 27115
To answer your first question, you can easily define this as an extension method as long as the method exists in a static class.
Secondly, if you check for Type.IsByRef
you will get only string and struct properties, both have a default implementation of Object.Equals.
Also this implementation will check for null and equality before doing the (expensive) by property comparison.
If you want to speed this up, you can use dynamic methods to do the comparison.
public static bool PropertiesEqual<T>(this T self, T other, params string[] skip)
{
if (self == null) return other == null;
if (self.Equals(other)) return true;
var properties = from p in typeof(T).GetProperties()
where !skip.Contains(p.Name)
&& !p.PropertyType.IsByRef // take only structs and string
select p;
foreach (var p in properties)
{
var selfValue = p.GetValue(self);
var otherValue = p.GetValue(other);
if (!object.Equals(selfValue, otherValue))
return false;
}
return true;
}
Upvotes: 2