Comparing all properties of an object using expression trees
- by stringargs
Hi,
I'm trying to write a simple generator that uses an expression tree to dynamically generate a method that compares all properties of an instance of a type to the properties of another instance of that type. This works fine for most properties, like int an string, but fails for DateTime? (and presumably other nullable value types).
The method:
static Delegate GenerateComparer(Type type)
{
var left = Expression.Parameter(type, "left");
var right = Expression.Parameter(type, "right");
Expression result = null;
foreach (var p in type.GetProperties())
{
var leftProperty = Expression.Property(left, p.Name);
var rightProperty = Expression.Property(right, p.Name);
var equals = p.PropertyType.GetMethod("Equals", new[] { p.PropertyType });
var callEqualsOnLeft = Expression.Call(leftProperty, equals, rightProperty);
result = result != null ? (Expression)Expression.And(result, callEqualsOnLeft) : (Expression)callEqualsOnLeft;
}
var method = Expression.Lambda(result, left, right).Compile();
return method;
}
On a DateTime? property it fails with:
Expression of type 'System.Nullable`1[System.DateTime]' cannot be used for parameter of type 'System.Object' of method 'Boolean Equals(System.Object)'
OK, so it finds an overload of Equals that expects object. So why can't I pass a DateTime? into that, as it's convertible to object? If I look at Nullable<T>, it indeed has an override of Equals(object o).
PS: I realize that this isn't a proper generator yet as it can't deal with null values, but I'll get to that :)