【问题标题】:How to assign properties generically using Expression.Assign selector with target type of object?如何使用具有目标类型的对象的 Expression.Assign 选择器一般地分配属性?
【发布时间】:2025-11-23 10:10:01
【问题描述】:

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

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 找到了可能的答案 here,但我无法让它工作。

【问题讨论】:

  • 使用 Expression.Convert 时什么不起作用?
  • 我尝试了 Expression.Convert 的各种组合,例如:Expression.Assign(Expression.Convert(prop.Item1.Body, prop.Item1.Body.Type), Expression.Convert(valueParameterExpression, prop.Item1.Body.Type)),但无济于事。有人可以帮忙吗?

标签: c# .net-4.0 expression


【解决方案1】:

好的,我使用以下代码完成了这项工作:

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,但是如果有人对此代码有任何改进,请随时提出建议!

【讨论】:

    最近更新 更多