2

我正在尝试使用表达式选择器将属性从一种类型的对象分配给另一种类型的对象,其中属性具有各种类型。这是我到目前为止的代码:

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));
    }
}

但是,我是 但是,当属性类型string. 我想这也会发生在除object. 知道如何使此代码适用于这种情况吗?

我在这里使用 Expression.Convert找到了一个潜在的答案,但我无法让它工作。

4

1 回答 1

4

好的,我使用以下代码进行了此操作:

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));
    }
}

这适用于可空类型(如评论)。我现在知道 Expression,但如果有人对此代码有任何改进,请随时提出建议!

于 2012-10-10T17:46:50.200 回答