Что-то вроде:
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);
}
Отлично. Благодарю. Он присваивал новый экземпляр переменной, которой я отсутствовал. Многие из них проходят через документы, и я все еще пропустил метод Expression.Variable. Большое спасибо – JRoughan