Эквивалент Expression.Assign в .Net 3.5? - PullRequest
3 голосов
/ 30 декабря 2010

В .Net 4.0 Microsoft добавила Expression.Assign. Я застрял с использованием 3,5, хотя. Я пытаюсь придумать некоторые способы написать метод, который может установить свойство объекта, но пока мне не повезло. Я могу сделать это:

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

Но я хочу избежать затрат на отражение! Свойства нельзя использовать с ref. Возможно ли это?

1 Ответ

8 голосов
/ 05 января 2011

Поскольку вы стремитесь избежать издержек на отражение, но имеете дело с деревьями выражений, я предполагаю, что вы пытаетесь скомпилировать выражение для делегата для установки свойства.

Все свойствапросто получить и установить методы за кулисами.Их можно вызывать - и это можно сделать в деревьях выражений .NET 3.5, используя Expression.Call.Например:

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