Подобно тому, как работают лямбда-выражения со свободными переменными, я хотел бы реализовать свой собственный класс замыкания, который захватывает некоторый параметр метода.
public class Closure<TObject, TVariable>
{
public TVariable Variable { get; set; }
public Func<TObject, bool> Predicate { get; set; }
}
Тогда у меня есть класс, который работает с DateTime
экземплярами. Один из методов, который должен использовать этот класс замыкания, таков:
// Original Version
public IEnumerable<Item> GetDayData(DateTime day)
{
this.items.Where(i => i.IsValidForDay(day));
}
Я хотел бы преобразовать его в класс Closure
. Проблема в том, что я хотел бы повторно использовать (из соображений производительности) мой экземпляр класса Closure
:
private Closure<Item, DateTime> closure = null;
public IEnumerable<Item> GetDayData(DateTime day)
{
if (closure == null)
{
this.closure = new Closure<Item, DateTime>() {
Variable = reference of "day" param, <=== HOW ????????
Predicate = i => i.IsValidForDay(this.closure.Variable)
}
}
this.items.Where(this.closure.Predicate);
}
Для того, чтобы я мог повторно использовать тот же экземпляр Closure
, мне нужно было бы сохранить не значение параметра (в поле Variable
замыкания), а указатель ссылки на параметр метода. Поэтому в следующий раз, когда этот метод будет вызван, замыкание Variable
будет фактически указывать на правильное значение, которое будет использоваться.
Как я должен это сделать ?
Подобное происходит, когда компилятор генерирует классы, которые захватывают переменные, не содержащие лямбда-выражения. Я смотрел на декомпилированный код (используя Reflector), но, похоже, я не понимаю, как это делается ...