After my post about dumping objects using expression trees, I've been asked if the same could be done for hydrating objects.
Sure it can, but it might not be that easy.
What we are looking for is a way to set properties on objects of an unknown type. For that, we need to generate methods to set each property of the objects.
Such methods would look like this expression:
Expression<Action<object, object>> expression = (o, v) =>
((SomeType)o).Property1 = (PropertyType)v;
Unfortunately, we cannot use the .NET Reflector trick because, if you try to compile this, you'll get this error:
error CS0832: An expression tree may not contain an assignment operator
Fortunately, that corresponds to a valid .NET expression tree. We just have to build it by hand.
So, for a given type, the set of property setters would be built this way:
var compiledExpressions = (from property in objectType.GetProperties()
let objectParameterExpression =
Expression.Parameter(typeof(object), "o")
let convertedObjectParameteExpressionr =
Expression.ConvertChecked(objectParameter, objectType)
let valueParameter = Expression.Parameter(propertyType, "v")
let convertedValueParameter =
Expression.ConvertChecked
(valueParameter, property.PropertyType)
let propertyExpression =
Expression.Property
(convertedObjectParameter, property)
select
Expression.Lambda<Action<object, object>>(
Expression.Assign(
propertyExpression,
convertedValueParameter
),
objectParameter,
valueParameter
).Compile()).ToArray();
And hydrating objects would be like this:
for (int o = 0; o < objects.Length; o++)
{
var objectProperties = objects[o];
var newObject = newObjects[o] = Activator.CreateInstance(objectType);
for (int p = 0; p < compiledExpressions.Length; p++)
{
compiledExpressions[p](newObject, objectProperties[p]);
}
}