一般采用前pression.Assign选择与对象的目标类型如何分配的属性? [英] How to assign properties generically using Expression.Assign selector with target type of object?
问题描述
我试图使用防爆pression选择一般性地分配属性,从一种类型的对象到另一个地方属性是不同类型的。这是code我到目前为止有:
I am trying to use an Expression selector to generically assign properties from one type of object to another where the properties are of various types. This is the code I have so far:
var type1 = new Type1();
var type2 = new Type2();
...
var propMap = new List<Tuple<Expression<Func<Type1, object>>, Expression<Func<TradeStaticAttributesItemModel, object>>>>
{
new Tuple<Expression<Func<Type1, object>>, Expression<Func<Type2, object>>>(x => x.Prop1, x => x.Prop1),
new Tuple<Expression<Func<Type1, object>>, Expression<Func<Type2, object>>>(x => x.Prop2, x => x.Prop2)
};
foreach (var prop in propMap)
{
if (prop.Item1.Compile()(type1) != prop.Item2.Compile()(type2))
{
ParameterExpression valueParameterExpression = Expression.Parameter(prop.Item2.Body.Type);
var assign = Expression.Lambda<Action<Type1, object>>(Expression.Assign(prop.Item1.Body, valueParameterExpression), prop.Item1.Parameters.Single(), valueParameterExpression);
Action<Type1, object> setter = assign.Compile();
setter(type1, prop.Item2.Compile()(type2));
}
}
不过,我可是,我发现了错误的ParameterEx $ P $类型'System.String'的的pssion不能用于类型为System.Object的委托参数的时候物业类型是字符串
。我想这也将发生任何其他类型以外对象
。任何想法如何使这项code工作这样的情况?
However, I am However, I'm getting the error "ParameterExpression of type 'System.String' cannot be used for delegate parameter of type 'System.Object'" when the type of property is a string
. I guess this would also happen for any other type other than object
. Any idea how to make this code work for such a situation?
我发现了一个可能的答案<一href="http://stackoverflow.com/questions/10760139/setting-property-without-knowing-target-type-at-compile-time">here使用防爆pression.Convert,但我不能让它的工作。
I found a potential answer here using Expression.Convert, but I can't get it to work.
推荐答案
OK,我用下面的code工作:
OK, I got this working with the following code:
var type1 = new Type1();
var type2 = new Type2();
...
var propMap = new List<Tuple<Expression<Func<Type1, object>>, Expression<Func<TradeStaticAttributesItemModel, object>>>>
{
new Tuple<Expression<Func<Type1, object>>, Expression<Func<Type2, object>>>(x => x.Prop1, x => x.Prop1),
new Tuple<Expression<Func<Type1, object>>, Expression<Func<Type2, object>>>(x => x.Prop2, x => x.Prop2)
};
foreach (var prop in propMap)
{
if (prop.Item1.Compile()(type1) != prop.Item2.Compile()(type2))
{
ParameterExpression valueParameterExpression = Expression.Parameter(typeof(object));
// This handles nullable types
Expression targetExpression = prop.Item1.Body is UnaryExpression ? ((UnaryExpression)prop.Item1.Body).Operand : prop.Item1.Body;
var assign = Expression.Lambda<Action<Type1, object>>(
Expression.Assign(targetExpression, Expression.Convert(valueParameterExpression, targetExpression.Type)),
prop.Item1.Parameters.Single(),
valueParameterExpression);
Action<Type1, object> setter = assign.Compile();
setter(type1, prop.Item2.Compile()(type2));
}
}
这适用于可空类型(如注释)。我现在知道前pression,但如果任何人有任何改进此code,请随时提出他们!
This works for nullable types (as commented). I now know Expression, but if anyone has any improvements for this code, please feel free to suggest them!
这篇关于一般采用前pression.Assign选择与对象的目标类型如何分配的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!