121 votes

Pourquoi certaines expressions lambda C # sont-elles compilées en méthodes statiques?

Comme vous pouvez le voir dans le code ci-dessous, j'ai déclaré un objet Action<> comme une variable.

Quelqu'un voudrait-il me faire savoir pourquoi ce délégué de méthode d'action se comporte comme une méthode statique?

Pourquoi renvoie-t-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();
}
 

Sortie:

exemple de sortie d'échantillon

152voto

Lukazoid Points 6577

C'est la plus probable, car il n'y a pas de fermetures, par exemple:

int age = 25;
Action<string> withClosure = s => Console.WriteLine("My name is {0} and I am {1} years old", s, age);
Action<string> withoutClosure = s => Console.WriteLine("My name is {0}", s);
Console.WriteLine(withClosure.Method.IsStatic);
Console.WriteLine(withoutClosure.Method.IsStatic);

Cela permettra de sortie false pour withClosure et true pour withoutClosure.

Lorsque vous utilisez une expression lambda, le compilateur crée un peu de classe à contenir votre méthode, ce serait de compiler quelque chose comme ce qui suit (la mise en œuvre réelle plus probable varie légèrement):

private class <Main>b__0
{
    public int age;
    public void withClosure(string s)
    {
        Console.WriteLine("My name is {0} and I am {1} years old", s, age)
    }
}

private static class <Main>b__1
{
    public static void withoutClosure(string s)
    {
        Console.WriteLine("My name is {0}", s)
    }
}

public static void Main()
{
    var b__0 = new <Main>b__0();
    b__0.age = 25;
    Action<string> withClosure = b__0.withClosure;
    Action<string> withoutClosure = <Main>b__1.withoutClosure;
    Console.WriteLine(withClosure.Method.IsStatic);
    Console.WriteLine(withoutClosure.Method.IsStatic);
}

Vous pouvez voir la Action<string> des cas le point de méthodes sur ces classes générées.

20voto

Peter O. Points 9967

La "méthode d'action" est statique seulement comme un effet secondaire de la mise en œuvre. C'est le cas d'une méthode anonyme sans capturé variables. Depuis il n'y a pas capturé variables, la méthode n'a pas de supplémentaires exigences de durée de vie au-delà de celles pour les variables locales en général. Si elle fait référence à d'autres variables locales, de sa durée de vie s'étend à toute la durée de vie de ces autres variables (voir sec. L. 1.7, les variables Locales, et de la sec. N. 15.5.1, Capturé extérieur variables, dans le C# 5.0 de la spécification).

Notez que la spécification C# ne parle que de méthodes anonymes être converti en "arbres d'expression", pas "anonyme classes". Alors que l'expression de l'arbre peut être représenté comme autres classes C#, par exemple, dans le compilateur de Microsoft, cette mise en œuvre n'est pas nécessaire (comme l'a reconnu par la sec. M. 5.3 dans le C# 5.0 de la spécification). Par conséquent, il n'est pas de savoir si la fonction anonyme est statique ou non. En outre, l'article K. 6 feuilles beaucoup plus ouverte que pour les détails de l'expression des arbres.

1voto

Mel Padden Points 653

La méthode n'a pas de fermeture 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 une fermeture, mais dans ce cas, elle n'est pas requise.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X