C# клонирование, включая лямбда-выражения
У меня есть лямбда-выражение, которое является функцией, которая выполняет некоторую операцию в предыдущем контексте. Следовательно, мне нужно будет клонировать этот объект и перенести выражение в новый контекст, но я обеспокоен тем, что в новое выражение будут перенесены локальные значения. Я попытался получить параметры в выражении и избежать локальных значений объекта, так что, надеюсь, это сведено к минимуму. Тем не менее, мой вопрос заключается в том, возможно ли клонировать выражение, и его скомпилированный вывод учитывает локальные значения нового объекта, а не старые?
Я могу проиллюстрировать, было ли это слово "картинка" недостаточно наглядным.
Я действую исходя из базового предположения, что на каком-то уровне действуют те же правила лямбда-выражений. То есть, как лямбда-выражения распознают локальные переменные в контексте выражения.
Спасибо...
1 ответ
Лямбда-выражение "rules" является частью компилятора C# (или любого языка, который вы используете); Само выражение не имеет автоматического знания контекста. Вместо этого, если вы "захватите" переменную, т.е. x
ниже:
int x = ...
Expression<Func<Foo, bool>> predicate = obj => obj.Bar == x;
компилятор создает экземпляр сгенерированного класса контекста и использует ConstantExpression
связать это с деревом:
// approximate representative code; not literal translation
var ctx = new SomeContext();
ctx.x = ... // x is actually a public instance field of SomeContext
var param = Expression.Parameter(typeof(Foo), "obj");
var predicate = Expression.Lambda<Func<Foo, bool>>(
Expression.Equal(
Expression.PropertyOrField(param, "Bar"),
Expression.PropertyOrField(Expression.Constant(ctx), "x")
), param);
Единственный способ "поменять" экземпляр контекста - переписать все выражение, как правило, через ExpressionVisitor
, Также обратите внимание, что вложенные области действия могут привести к более сложным сценариям, включающим связанные объекты контекста.
Лично; Я сомневаюсь, что вам нужно беспокоиться об этом.