We know that int is a value type and so the following makes sense:
int x = 3;
int y = x;
y = 5;
Console.WriteLine(x); //says 3.
Now, here is a
Here is a full solution:
// Credits to digEmAll for the following code
public delegate void Setter(T newValue);
public delegate T Getter();
public class MagicPointer
{
private Getter getter;
private Setter setter;
public T Value
{
get { return getter(); }
set { setter(value); }
}
public MagicPointer(Getter getter, Setter setter)
{
this.getter = getter;
this.setter = setter;
}
}
// Code starting from here is mine
public static class MagicUtilClass
{
public static MagicPointer LinkVariable(Expression> expression)
{
var memberExpr = expression.Body as MemberExpression;
if (memberExpr == null)
throw new InvalidOperationException("The body of the expression is expected to be a member-access expression.");
var field = memberExpr.Member as FieldInfo;
if (field == null)
throw new InvalidOperationException("The body of the expression is expected to be a member-access expression that accesses a field.");
var constant = memberExpr.Expression as ConstantExpression;
if (constant == null)
throw new InvalidOperationException("The body of the expression is expected to be a member-access expression that accesses a field on a constant expression.");
return new MagicPointer(() => (T) field.GetValue(constant.Value),
x => field.SetValue(constant.Value, x));
}
}
Usage:
int x = 47;
var magic = MagicUtilClass.LinkVariable(() => x);
magic.Value = 48;
Console.WriteLine(x); // Outputs 48
To understand why this solution works, you need to know that the compiler transforms your code quite considerably whenever you use a variable inside a lambda expression (irrespective of whether that lambda expression becomes a delegate or an expression tree). It actually generates a new class containing a field. The variable x is removed and replaced with that field. The Usage example will then look something like this:
CompilerGeneratedClass1 locals = new CompilerGeneratedClass1();
locals.x = 47;
var magic = MagicUtilClass.LinkVariable(() => locals.x);
// etc.
The “field” that the code retrieves is the field containing x, and the “constant” that it retrieves is the locals instance.