При компиляции деревьев выражений C # в методы возможно ли получить доступ к "this"? - PullRequest
4 голосов
/ 08 мая 2019

Я пытаюсь динамически генерировать класс, который реализует данный интерфейс. Из-за этого мне нужно реализовать некоторые методы. Я хотел бы избежать прямого генерирования инструкций IL, поэтому я пытаюсь использовать деревья выражений и CompileToMethod. К сожалению, некоторым из этих методов требуется доступ к полю сгенерированного класса (как будто я записал this.field в метод, который я реализую). Можно ли получить доступ к «этому», используя деревья выражений? (Под «этим» я подразумеваю объект, к которому будет вызван метод.)

Если да, как будет выглядеть такой метод с деревьями выражений?

int SomeMethod() {
    return this.field.SomeOtherMethod();
}

1 Ответ

2 голосов
/ 09 мая 2019

Expression.Constant или ParameterExpression ваши друзья;Примеры:

var obj = Expression.Constant(this);
var field = Expression.PropertyOrField(obj, "field");
var call = Expression.Call(field, field.Type.GetMethod("SomeOtherMethod"));
var lambda = Expression.Lambda<Func<int>>(call);

или:

var obj = Expression.Parameter(typeof(SomeType));
var field = Expression.PropertyOrField(obj, "field");
var call = Expression.Call(field, field.Type.GetMethod("SomeOtherMethod"));
var lambda = Expression.Lambda<Func<SomeType, int>>(call, obj);

(в последнем случае вы передадите this в качестве параметра, но это означает, что вы можете сохранить лямбда и перевести-используйте его для различных целевых объектов экземпляра)

Другой вариант здесь может быть dynamic, если ваши имена фиксированы:

dynamic obj = someDuckTypedObject;
int i = obj.field.SomeOtherMethod();
...