Josh Close
Josh Close

Reputation: 23383

Expression to Set Properties on Existing Object Instance

How can I use Expression to set properties on an instance of an object I already have? I don't want to create a new object, so Expression.New where you can pass in member initializers won't work.

This is not a duplicate of How to set property value using Expressions? because that takes an Expression and sets properties via Reflection.

I have an existing object and want to create an Expression where I can set properties. That expression will then get compiled into a delegate to execute.

Upvotes: 1

Views: 3760

Answers (2)

MBoros
MBoros

Reputation: 1140

what about:

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

}

Remember that the expression is just a definition of what should be done, you have to compile it to a delegate to be able to invoke it.

Upvotes: 4

Josh E
Josh E

Reputation: 7432

Have you looked at using MemberAssignment to set the value of the member(s)?

Represents assignment operation for a field or property of an object.

Important note in the remarks, however: you can't create these directly. Instead,

Use the Bind factory methods to create a MemberAssignment. A MemberAssignment has the BindingType property equal to Assignment.

Upvotes: 1

Related Questions