Reputation: 23383
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
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
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