2013-08-12 2 views
0

Если я объявил в космическом дереве выражения:Pass значение, генерируемое в Expression дерева поддерева

var creatorExpression = Expression.New(targetType); 

И я хочу использовать это в одном или суб-выражений, которые присваивают значения для свойств новый пример, например:

var assignmentExpression = Expression.Assign(targetMemberExpression, valueExpression); 

Как я могу это сделать?

В настоящее время я помещаю все выражения присваивания в Expression.Block, но я не вижу способа передать экземпляр в этот блок. Он принимает ParameterExpressions, но я не передаю экземпляр; Я передаю тип, который нужно построить.

ответ

2

Что-то вроде:

Type targetType = typeof(MyClass); 

var obj = Expression.Variable(targetType); 

var creatorExpression = Expression.New(targetType); 
var assign = Expression.Assign(obj, creatorExpression); 

var prop = Expression.PropertyOrField(obj, "MyProp1"); 
var value = Expression.Constant(5); 
var member = Expression.Assign(prop, value); 

var block = Expression.Block(new[] { obj }, creatorExpression, assign, member); 

Вы должны помнить, что Expression.New(targetType) является new something(), так что если вы используете его непосредственно где-то еще, вы каждый раз, когда воссоздание объекта. Вы не хотите:

new MyClass().MyProp1 = 5; 
new MyClass().MyProp2 = 6; 

вы хотите

var obj = new MyClass(); // assign + creatorExpression 
obj.MyProp1 = 5; // member + prop + value 
obj.MyProp2 = 6; // not in the example 

Если вы знаете, что свойство/поле вы обращаетесь это свойство или поле вы можете использовать Expression.Property или Expression.Field. Оба принимают string как имя свойства/поля или PropertyInfo/MethodInfo, которые могут быть получены путем отражения.

Если у вас есть функция, которая делает назначение и возвращает блок с заданиями, вы можете перейти к нему obj выражению, как:

BlockExpression MakeSomeAssignments(ParameterExpression obj, Expression value1, int value2) 
{ 
    var prop1e = Expression.PropertyOrField(obj, "MyProp1"); 
    var member1e = Expression.Assign(prop1e, value1e); 

    var prop2e = Expression.PropertyOrField(obj, "MyProp2"); 
    var value2e = Expression.Constant(value2); 
    var member2e = Expression.Assign(prop2e, value2e); 

    return new Expression.Block(member1e, member2e); 
} 
+0

Отлично. Благодарю. Он присваивал новый экземпляр переменной, которой я отсутствовал. Многие из них проходят через документы, и я все еще пропустил метод Expression.Variable. Большое спасибо – JRoughan

Смежные вопросы