Expression.Assign
.NET 4 より前では使用できません。元の署名を使用して、このメソッドを .NET 3.5 で実装する必要があります。
public static BinaryExpression Assign(
Expression left,
Expression right
)
明確化: 場合によっては、このメソッドを使用する方法を探しているわけではありません。一般的なケースを実装する必要があります。
Expression.Assign
.NET 4 より前では使用できません。元の署名を使用して、このメソッドを .NET 3.5 で実装する必要があります。
public static BinaryExpression Assign(
Expression left,
Expression right
)
明確化: 場合によっては、このメソッドを使用する方法を探しているわけではありません。一般的なケースを実装する必要があります。
がないため、正確に同等のものを取得することはできませんが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
できるので、それほどハックではありません。
私はあなたができないことを恐れています。
理由は次のとおりです。
ExpressionType
Assign
列挙には3.5 のメンバーが含まれていません。Expression.MakeBinary()
してバイナリ式を作成しようとしましたが、そのメソッドは無視されます。(結果の BinaryExpression には、 standardMethod
またはMethod
= null のいずれかが含まれます。)Method
。これは読み取り専用であり、クラスは封印されているため、派生クラスでそれを回避することはできません。しかし、彼らはそのmethod
引数をMakeBinary()
に含めたので、まだいくつかの回避策が存在する可能性があります...それが不可能であると100%確信しているわけではありません。
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);