Yes, you can, a local variable is captured in an object that will be stored as a constant in the expression tree.
You can either compile a new method that sets the value of the captured field:
public static void SetMember<T>(Expression<Func<T>> memberExpression, T newVlaue)
{
var body = (MemberExpression)memberExpression.Body;
var name = body.Member.Name;
var newValueParam = Expression.Parameter(typeof(T));
var newBody = Expression.Assign(body, newValueParam);
var setter = Expression.Lambda<Action<T>>(newBody, newValueParam).Compile();
setter(newVlaue);
}
Or you can use constant reflection
public static void SetMember<T>(Expression<Func<T>> memberExpression, T newVlaue)
{
var body = (MemberExpression)memberExpression.Body;
var name = body.Member.Name;
var constant = body.Expression as ConstantExpression;
(body.Member as FieldInfo).SetValue(constant.Value, newVlaue);
}
, , , . . , , # Roslyn, , - , " ", , .
out/ref, , nameof, - , , .
public static void SetMember<T>(ref T local, T newValue, string nameOfLocal)
{
local = newValue;
}
static void Main(string[] args)
{
var text = "test";
SetMember(ref text, "new value", nameof(text));
Console.Write(text);
}