3

Expression.Assign.NET 4 より前では使用できません。元の署名を使用して、このメソッドを .NET 3.5 で実装する必要があります。

public static BinaryExpression Assign(
    Expression left,
    Expression right
)

明確化: 場合によっては、このメソッドを使用する方法を探しているわけではありません。一般的なケースを実装する必要があります。

4

3 に答える 3

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できるので、それほどハックではありません。

于 2012-04-12T12:54:18.500 に答える
0

私はあなたができないことを恐れています。

理由は次のとおりです。

  1. ExpressionTypeAssign列挙には3.5 のメンバーが含まれていません。
  2. 間違った ExpressionType を使用して、メソッドを使用Expression.MakeBinary()してバイナリ式を作成しようとしましたが、そのメソッドは無視されます。(結果の BinaryExpression には、 standardMethodまたはMethod= null のいずれかが含まれます。)
  3. インスタンスで割り当てることはできませんMethod。これは読み取り専用であり、クラスは封印されているため、派生クラスでそれを回避することはできません。

しかし、彼らはそのmethod引数をMakeBinary()に含めたので、まだいくつかの回避策が存在する可能性があります...それが不可能であると100%確信しているわけではありません。

于 2012-04-12T12:34:16.863 に答える
0

Konstantin Oznobihin の splution に基づいて、 a のMethodCallExpression代わりにを含むわずかに変更されたものを以下に示しBinaryExpressionます。

public class ExpressionEx
{
    public static Expression Assign(Expression left, Expression right)
    {
        var method = typeof(ExpressionEx).GetMethod("Assign", BindingFlags.Static | BindingFlags.NonPublic).MakeGenericMethod(left.Type);
        return Expression.Call(method, left, right);
    }
    private static void Assign<T>(ref T left, T right)
    {
        left = right;
    }
}

Assignこれにより、内部の-methodへのデリゲートが作成され、次のExpressionExように簡単に使用できるようになります。

var expr = ExpressionEx.Assign(myInstanceExpression, newValueExpression);
于 2017-12-05T17:04:39.317 に答える