一般采用前pression.Assign选择与对象的目标类型如何分配的属性? [英] How to assign properties generically using Expression.Assign selector with target type of object?

查看:176
本文介绍了一般采用前pression.Assign选择与对象的目标类型如何分配的属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用防爆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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆