здесь появляется сообщение об ошибке: «CS1628 Невозможно использовать ref, out или в параметре 'seq' внутри анонимного метода, лямбда-выражения, выражения запроса или локальной функции» - seq2
- это лямбда-выражение; это не имеет ничего общего с ссылочными типами, а скорее: время жизни. Вы могли бы, в конце концов, назвать это как:
void Foo() {
Sequence bar = SomeMethod; // bar is a LOCAL of Foo
F(ref bar);
// not shown: perhaps do something with bar, perhaps not
}
В этот момент F
потребуется каким-то образом создать лямбду, содержащую в себе ссылку на позицию в стеке (ссылку на локальный bar
). Теперь обратите внимание, что эта лямбда, будучи объектом, может пережить Foo
, а bar
будет неопределенным - и, возможно, многократно используемым - местом в памяти.
Итак: вы не можете «захватить» параметры, которые передаются как ref
, in
наш out
, где я использую здесь «захват» свободно, чтобы означать «использование в рамках лямбды или анонимный метод, который формирует дерево выражений, выражение делегата или внутри блока итератора или асинхронного продолжения ".
Просто удалите ref
. Вам это не нужно, и это не помогает. Если вы намереваетесь изменить делегата, то вместо этого рассмотрите возврат составного делегата.
в качестве альтернативы: снимите значение и сделайте снимок:
void F(ref Sequence seq)
{
var tmp = seq;
seq = r =>
{
if (r % 2 == 0)
return tmp(r);
else
return tmp(2 * r);
};
}
это позволяет избежать проблемного сценария, поскольку снимок разыменовывает параметр ref
, что означает: теперь нет никакой возможности захватить расположение стека.