Comme vous pouvez le voir dans le code ci-dessous, j'ai déclaré un Action<>
objet en tant que variable.
Quelqu'un pourrait-il me faire savoir pourquoi ce délégué de méthode d'action se comporte comme une méthode statique?
Pourquoi revient-il true
dans le code suivant?
Code:
public static void Main(string[] args)
{
Action<string> actionMethod = s => { Console.WriteLine("My Name is " + s); };
Console.WriteLine(actionMethod.Method.IsStatic);
Console.Read();
}
Production:
c#
.net
reflection
lambda
Nunu
la source
la source
static
méthodes.Ildasm
est vraiment utile pour comprendre ce qui se passe réellement, j'ai tendance à utiliser l'IL
ongletLINQPad
pour examiner de petits échantillons.IL
ongletLINQPad
et déduit le C #. Certaines options pour obtenir l'équivalent C # réel de la sortie compilée consisteraient à utiliserILSpy
ouReflector
sur l'assembly compilé, vous devrez probablement désactiver certaines options qui tenteront d'afficher les lambdas et non les classes générées par le compilateur.La "méthode d'action" n'est statique qu'en tant qu'effet secondaire de l'implémentation. Il s'agit d'un cas de méthode anonyme sans variables capturées. Comme il n'y a pas de variables capturées, la méthode n'a pas d'exigences de durée de vie supplémentaires au-delà de celles des variables locales en général. S'il faisait référence à d'autres variables locales, sa durée de vie s'étend à la durée de vie de ces autres variables (voir sec. L.1.7, Variables locales , et sec. N.15.5.1, Variables externes capturées , dans la spécification C # 5.0).
Notez que la spécification C # ne parle que des méthodes anonymes converties en "arbres d'expression", et non en "classes anonymes". Bien que l'arborescence d'expression puisse être représentée comme des classes C # supplémentaires, par exemple, dans le compilateur Microsoft, cette implémentation n'est pas requise (comme reconnu par la sec. M.5.3 dans la spécification C # 5.0). Par conséquent, il n'est pas défini si la fonction anonyme est statique ou non. De plus, la section K.6 laisse beaucoup de place aux détails des arbres d'expression.
la source
Le comportement de mise en cache des délégués a été modifié dans Roslyn. Auparavant, comme indiqué, toute expression lambda qui ne capturait pas de variables était compilée dans une
static
méthode sur le site d'appel. Roslyn a changé ce comportement. Désormais, tout lambda, qui capture ou non des variables, est transformé en classe d'affichage:Compte tenu de cet exemple:
Sortie du compilateur natif:
Roslyn:
Les changements de comportement de mise en cache des délégués dans Roslyn expliquent pourquoi cette modification a été apportée.
la source
À partir de C # 6, ce sera toujours par défaut les méthodes d'instance maintenant, et ne sera jamais statique (donc
actionMethod.Method.IsStatic
sera toujours faux).Voir ici: Pourquoi un lambda sans capture est-il passé d'une méthode statique en C # 5 à une méthode d'instance en C # 6?
et ici: Différence dans l'évaluation de l'expression lambda statique du compilateur CSC et Roslyn?
la source
La méthode n'a pas de fermetures et fait également référence à une méthode statique elle-même (Console.WriteLine), donc je m'attendrais à ce qu'elle soit statique. La méthode déclarera un type anonyme englobant pour une fermeture, mais dans ce cas, ce n'est pas obligatoire.
la source