Почему вы не можете использовать параметр ref или out в лямбда-выражении?
Сегодня я столкнулся с ошибкой и нашел обходной путь, но мне все еще было любопытно, почему это ошибка времени компиляции.
CS1628 : невозможно использовать в ref или out параметр 'parameter' внутри анонимного метода, лямбда-выражения или выражения запроса
Вот простой пример:
private void Foo()
{
int value;
Bar(out value);
}
private void Bar(out int value)
{
value = 3;
int[] array = { 1, 2, 3, 4, 5 };
int newValue = array.Where(a => a == value).First();
}
Ответы:
Лямбды имеют вид изменения времени жизни переменных, которые они захватывают. Например, следующее лямбда-выражение заставляет параметр p1 жить дольше, чем текущий фрейм метода, так как к его значению можно получить доступ после того, как фрейм метода больше не находится в стеке.
Другое свойство захваченных переменных заключается в том, что изменения в переменной также видны вне лямбда-выражения. Например, следующие отпечатки 42
Эти два свойства производят определенный набор эффектов, которые сталкиваются с параметром ref следующими способами
Это несколько несовместимые свойства, и они являются одной из причин, по которой они запрещены в лямбда-выражениях.
источник
ref
внутри лямбда-выражения, но желание использовать его не было удовлетворено.Под капотом анонимный метод реализуется путем подъема захваченных переменных (о чем и состоит ваше тело вопроса) и сохранения их в виде полей сгенерированного компилятором класса. Нет способа сохранить параметр
ref
илиout
как поле. Эрик Липперт обсуждал это в записи в блоге . Обратите внимание, что есть разница между захваченными переменными и лямбда-параметрами. Вы можете иметь «формальные параметры», подобные следующим, поскольку они не являются захваченными переменными:источник
Вы можете, но вы должны явно определить все типы так
Неверно, однако
Действует
источник
ref
илиout
внутри лямбда-выражения. Понятно, если вы читаете пример кода (попробуйте еще раз, чтобы прочитать его снова). Принятый ответ четко объясняет почему. Ваш ответ об использованииref
илиout
параметре лямбда. Совершенно не отвечая на вопрос и говоря о чем-то другомТак как это один из лучших результатов для "C # lambda ref" в Google; Я чувствую, что мне нужно расширить эти ответы. Старый (C # 2.0) синтаксис анонимного делегата работает и поддерживает более сложные подписи (а также замыкания). Лямбда и анонимные делегаты, по крайней мере, имеют общую воспринимаемую реализацию в бэкенде компилятора (если они не идентичны) - и, самое главное, они поддерживают замыкания.
Что я пытался сделать, когда делал поиск, чтобы продемонстрировать синтаксис:
Просто имейте в виду, что Lambdas процедурно и математически более безопасны (из-за упомянутой выше рекламы ref value): вы можете открыть банку с червями. Тщательно продумайте этот синтаксис.
источник
(a, b, c, ref d) => {...}
иref
был подчеркнут красным с сообщением об ошибке «Параметр« 4 »должен быть объявлен с ключевым словом ref». Facepalm! PS что такое "продвижение стоимости ref"?А может это?
источник