使用表达式树填充对象 - 第 I 部分





5.00/5 (3投票s)
使用表达式树填充对象。
在我发表关于使用表达式树转储对象的文章后,有人问是否可以对对象进行水合处理。
当然可以,但这可能并不容易。
我们想要的是一种设置未知类型对象属性的方法。为此,我们需要生成方法来设置对象的每个属性。
这些方法看起来会像这个表达式
Expression<Action<object, object>> expression = (o, v) =>
((SomeType)o).Property1 = (PropertyType)v;
不幸的是,我们不能使用.NET Reflector 技巧,因为如果你尝试编译这个,你会得到这个错误
error CS0832: An expression tree may not contain an assignment operator
幸运的是,这对应于一个有效的.NET表达式树。我们只需要手动构建它。
因此,对于给定的类型,属性设置器的集合将以这种方式构建
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();
而对象水合会像这样
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]);
}
}