Como você pode ver no código abaixo, declarei um Action<>
objeto como uma variável.
Alguém poderia me informar por que esse delegado do método de ação se comporta como um método estático?
Por que ele retorna true
no código a seguir?
Código:
public static void Main(string[] args)
{
Action<string> actionMethod = s => { Console.WriteLine("My Name is " + s); };
Console.WriteLine(actionMethod.Method.IsStatic);
Console.Read();
}
Resultado:
c#
.net
reflection
lambda
nunu
fonte
fonte
static
métodos.Ildasm
é realmente útil para entender o que realmente está acontecendo; costumo usar aIL
guiaLINQPad
para examinar pequenas amostras.IL
guiaLINQPad
e inferi o C #. Algumas opções para obter o equivalente C # real da saída compilada seriam usarILSpy
ouReflector
no assembly compilado, você provavelmente precisará desativar algumas opções que tentarão exibir as lambdas e não as classes geradas pelo compilador.O "método de ação" é estático apenas como efeito colateral da implementação. Este é um caso de um método anônimo sem variáveis capturadas. Como não há variáveis capturadas, o método não possui requisitos de vida útil adicionais além daqueles para variáveis locais em geral. Se ele fez referência a outras variáveis locais, sua vida útil se estende à vida útil dessas outras variáveis (consulte a seção L.1.7, Variáveis locais e a seção N.15.5.1, Variáveis externas capturadas , na especificação C # 5.0).
Observe que a especificação C # fala apenas sobre métodos anônimos sendo convertidos em "árvores de expressão", não em "classes anônimas". Embora a árvore de expressão possa ser representada como classes C # adicionais, por exemplo, no compilador da Microsoft, essa implementação não é necessária (conforme reconhecido pela seção M.5.3 na especificação C # 5.0). Portanto, não está definido se a função anônima é estática ou não. Além disso, a seção K.6 deixa muito aberto quanto aos detalhes das árvores de expressão.
fonte
O comportamento do cache de delegado foi alterado em Roslyn. Anteriormente, como declarado, qualquer expressão lambda que não capturasse variáveis foi compilada em um
static
método no site de chamada. Roslyn mudou esse comportamento. Agora, qualquer lambda, que captura variáveis ou não, é transformado em uma classe de exibição:Dado este exemplo:
Saída do compilador nativo:
Roslyn:
Delegar alterações de comportamento de cache em Roslyn fala sobre por que essa alteração foi feita.
fonte
A partir do C # 6, isso sempre adotará como padrão os métodos de instância agora e nunca será estático (portanto
actionMethod.Method.IsStatic
, sempre será falso).Veja aqui: Por que um lambda sem captura foi alterado de estático no C # 5 para um método de instância no C # 6?
e aqui: Diferença na avaliação da expressão lambda estática do compilador CSC e Roslyn?
fonte
O método não tem fechamentos e também faz referência a um método estático (Console.WriteLine), portanto, espero que seja estático. O método declarará um tipo anônimo de fechamento para um fechamento, mas, neste caso, não é necessário.
fonte