How to set local variable memberExpression

I want to get the original name of the parameter and update its value. How can i do this?

public void SetMember<T>(Expression<Func<T>> memberExpression)
{
    var body = (MemberExpression)memberExpression.Body;
    var name = body.Member.Name; //text

    //can I set variable value here 
}

static void Main(string[] args)
{
    var text="test";
    SetMember(() => text);
}
+4
source share
1 answer

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; //text
    var newValueParam = Expression.Parameter(typeof(T));
    var newBody = Expression.Assign(body, newValueParam);

    var setter = Expression.Lambda<Action<T>>(newBody, newValueParam).Compile();
    setter(newVlaue); // Set with the new value 
}

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; //text
    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;
    // nameofLocal can be used ..
}

static void Main(string[] args)
{
    var text = "test";
    SetMember(ref text, "new value", nameof(text));
    Console.Write(text);
}
+5
source

Source: https://habr.com/ru/post/1694224/


All Articles