Por que você não pode usar um parâmetro ref ou out em uma expressão lambda?
Encontrei o erro hoje e encontrei uma solução alternativa, mas ainda estava curioso por que esse é um erro em tempo de compilação.
CS1628 : Não é possível usar no parâmetro ref ou out 'parameter' dentro de um método anônimo, expressão lambda ou expressão de consulta
Aqui está um exemplo simples:
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();
}
Respostas:
Os lambdas parecem alterar o tempo de vida das variáveis que eles capturam. Por exemplo, a seguinte expressão lambda faz com que o parâmetro p1 viva mais que o quadro de método atual, pois seu valor pode ser acessado depois que o quadro de método não estiver mais na pilha
Outra propriedade das variáveis capturadas é que as alterações na variável também são visíveis fora da expressão lambda. Por exemplo, as seguintes impressões 42
Essas duas propriedades produzem um certo conjunto de efeitos que voam na face de um parâmetro ref das seguintes maneiras
Essas são propriedades um tanto incompatíveis e são uma das razões pelas quais elas não são permitidas nas expressões lambda.
fonte
ref
expressão lambda dentro, mas o desejo de usá-la não foi alimentado.Sob o capô, o método anônimo é implementado ao içar variáveis capturadas (que é o objetivo do seu corpo de perguntas) e armazená-las como campos de uma classe gerada pelo compilador. Não há como armazenar um
ref
ouout
parâmetro como um campo. Eric Lippert discutiu isso em uma entrada de blog . Observe que há uma diferença entre variáveis capturadas e parâmetros lambda. Você pode ter "parâmetros formais" como os seguintes, pois não são variáveis capturadas:fonte
Você pode, mas deve definir explicitamente todos os tipos para
É inválido, no entanto
É válido
fonte
ref
ouout
dentro de uma lambda. É claro se você ler o código de exemplo (tente novamente para lê-lo novamente). A resposta aceita explica claramente o porquê. Sua resposta é sobre o usoref
ouout
parâmetro para o lambda. Totalmente não responder a questão e falar sobre outra coisaComo esse é um dos principais resultados para "C # lambda ref" no Google; Sinto que preciso expandir as respostas acima. A sintaxe de delegado anônimo mais antiga (C # 2.0) funciona e suporta assinaturas mais complexas (além de fechamentos). Os delegados anônimos e da Lambda, no mínimo, compartilharam a implementação percebida no back-end do compilador (se não forem idênticos) - e o mais importante, eles suportam fechamentos.
O que eu estava tentando fazer quando fiz a pesquisa, para demonstrar a sintaxe:
Lembre-se de que as Lambdas são processualmente e matematicamente mais seguras (devido à promoção do valor de referência mencionada anteriormente): você pode abrir uma lata de worms. Pense com cuidado ao usar esta sintaxe.
fonte
(a, b, c, ref d) => {...}
eref
fui sublinhado em vermelho com a mensagem de erro "O parâmetro '4' deve ser declarado com a palavra-chave 'ref'". Facepalm! PS o que é "promoção de valor ref"?E talvez isso?
fonte