相当于Expression.Assign .Net 3.5?

时间:2010-12-30 17:10:55

标签: c# .net-3.5 .net-4.0 expression-trees

在.Net 4.0中,Microsoft添加了Expression.Assign。不过,我坚持使用3.5。我试图想出一些方法来编写一个可以设置对象属性的方法,但到目前为止我还没有多少运气。我可以这样做:

public void Assign(object instance, PropertyInfo pi, object value)
{
    pi.SetValue(instance, value, null);
}

但我想避免使用反射的开销!属性不能与ref一起使用。这可能吗?

1 个答案:

答案 0 :(得分:8)

由于你的目标是避免反射的开销但是处理表达式树,我假设你正在尝试将表达式编译成委托以设置属性。

所有属性都只是在幕后获取和设置方法。可以调用它们 - 这可以使用Expression.Call在.NET 3.5表达式树中完成。例如:

class Test{ public int X {get;set;} }

//...elsewhere
var xPropSetter = typeof(Test)
    .GetProperty("X",BindingFlags.Instance|BindingFlags.Public)
    .GetSetMethod();
var newValPar=Expression.Parameter(typeof(int));
var objectPar=Expression.Parameter(typeof(Test));
var callExpr=Expression.Call(objectPar, xPropSetter, newValPar);
var setterAction = (Action<Test,int>)
    Expression.Lambda(callExpr, objectPar, newValPar).Compile();
Test val = new Test();
Console.WriteLine(val.X);//0
setterLambda(val,42);
Console.WriteLine(val.X);//42

请注意,如果你想要的只是一个设置值的委托,你也可以在不使用表达式树的情况下创建委托:

var setterAction = (Action<Test,int>)
    Delegate.CreateDelegate(typeof(Action<Test,int>), xPropSetter);