Expression.Assign
不可用。我需要使用原始签名在此方法的.NET 3.5下实现:
public static BinaryExpression Assign(
Expression left,
Expression right
)
澄清:在某些情况下,我不是在寻找使用此方法的方法。我需要实施一般情况。
答案 0 :(得分: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。
答案 1 :(得分:0)
我怕你不能。
原因如下:
ExpressionType
枚举在3.5中不包含Assign
成员。Expression.MakeBinary()
创建二进制表达式,但该方法被忽略。 (结果BinaryExpression具有标准Method
或Method
= null。)Method
- 它是只读的,并且类是密封的,所以你不能在派生类中解决它。但是因为他们已经将method
参数包含在MakeBinary()
中,所以仍然可能存在一些解决方法......我不是百分之百确定它是不可能的。
答案 2 :(得分:0)
基于Konstantin Oznobihin的洗脱,这是一个含有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
内创建ExpressionEx
- 方法的委托,现在可以像这样轻松使用:
var expr = ExpressionEx.Assign(myInstanceExpression, newValueExpression);