Implementation of Expression.Assign in .Net 3.5 with same signature?

.net-3.5, .net-4.0, c#, expression, expression-trees

Solution

You can't get exact equivalent since there is no `ExpressionType.Assign`, but it's possible to make something similar:

public static class ExpressionEx
{
    public static BinaryExpression Assign(Expression left, Expression right)
    {
        var assign = typeof(Assigner<>).MakeGenericType(left.Type).GetMethod("Assign");

        var assignExpr = Expression.Add(left, right, assign);

        return assignExpr;
    }

    private static class Assigner<T>
    {
        public static T Assign(ref T left, T right)
        {
            return (left = right);
        }
    }
}

Then you can use it for generating assignments:

class Foo
{
    public int Data
    {
        get;
        set;
    }
}

class Program
{
    static Action<object, object> MakeSetter(PropertyInfo info)
    {
        var objectParameter = Expression.Parameter(typeof(object), string.Empty);
        var valueParameter = Expression.Parameter(typeof(object), string.Empty);
        var setterExpression = Expression.Lambda<Action<object, object>>(
            ExpressionEx.Assign(
                Expression.Property(
                    Expression.Convert(objectParameter, info.DeclaringType),
                    info),
                Expression.Convert(valueParameter, info.PropertyType)),
            objectParameter,
            valueParameter);

        return setterExpression.Compile();
    }

    static void Main()
    {
        var foo = new Foo();
        var property = typeof(Foo).GetProperty("Data");

        var setter = MakeSetter(property);
        setter(foo, 10);
        Console.WriteLine(foo.Data);
    }
}

If you don't really need `BinaryExpression` as a return type you could use `Expression.Call` instead of `Add` so it would be not so hackish.

Problem

`Expression.Assign` isn't available before .NET 4. I need to implementation under .NET 3.5 of this method with original signature: ``` public static BinaryExpression Assign( Expression left, Expression right ) ``` Clarification: I'm not looking for a way to use this method in the some case. I need to implement the general case.

Original source