在现有对象实例上设置属性的表达式

时间:2017-09-22 22:25:20

标签: c# linq lambda expression-trees

如何使用Expression在我已有的对象实例上设置属性?我不想创建新对象,因此您可以传递成员初始化程序的Expression.New无法正常工作。

这与How to set property value using Expressions?不重复,因为它需要Expression并通过Reflection设置属性。

我有一个object,我想创建一个Expression,我可以在其中设置属性。然后该表达式将被编译为delegate以执行。

2 个答案:

答案 0 :(得分:2)

怎么样:

public class User {
    public string Name {get;set;}
}

public static void Main()
{
    var user = new User();
    var assigner = GetAssigner<User, string>(u => u.Name);
    assigner.Compile()(user, "Joe");
    Console.WriteLine(user.Name);
}

public static Expression<Action<TClass, TValue>> GetAssigner<TClass, TValue>(Expression<Func<TClass, TValue>> propertyAccessor){
    var prop = ((MemberExpression)propertyAccessor.Body).Member;
    var typeParam = Expression.Parameter(typeof(TClass));
    var valueParam = Expression.Parameter(typeof(TValue));
    return Expression.Lambda<Action<TClass, TValue>>(
        Expression.Assign(
            Expression.MakeMemberAccess(typeParam, prop),
            valueParam), typeParam, valueParam);

}

请记住,表达式只是应该完成的定义,您必须将其编译为委托以便能够调用它。

答案 1 :(得分:1)

您是否考虑过使用MemberAssignment来设置成员的值?

  

表示对象的字段或属性的赋值操作。

备注中的重要说明:您无法直接创建这些注释。相反,

  

使用Bind工厂方法创建MemberAssignment。   MemberAssignment的BindingType属性等于Assignment