Expression.Assign在.Net 3.5中的实现具有相同的签名?

And*_*hin 3 c# expression .net-4.0 expression-trees .net-3.5

Expression.Assign 在.NET 4之前不可用.我需要使用原始签名在此方法的.NET 3.5下实现:

public static BinaryExpression Assign(
    Expression left,
    Expression right
)
Run Code Online (Sandbox Code Playgroud)

澄清:在某些情况下,我不是在寻找使用此方法的方法.我需要实施一般情况.

Kon*_*hin 6

你不能得到确切的等价物,因为没有ExpressionType.Assign,但它可以做出类似的东西:


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);
        }
    }
}

然后你可以用它来生成作业:


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);
    }
}

如果你真的不需要BinaryExpression作为一种返回类型,你可以使用Expression.Call而不是Add这样,它就不会那么hackish.