58 votes

Les expressions Lambda sont-elles dans des fermetures C #?

Sont des expressions lambda (et à un degré, fonctions anonymes), les fermetures?

Ma compréhension de fermetures sont qu'ils sont des fonctions qui sont traitées comme des objets, ce qui semble être une représentation exacte de ce que les fonctions anonymes et les expressions Lambda ne.

Et est-il correct de les appeler les bouchons? Je comprends que la fermeture est venu sur (ou est devenu populaire) en raison du dialecte de lisp, mais c'est aussi une programmation générale terme?

Merci pour les éclaircissements que vous pouvez offrir!

110voto

Reed Copsey Points 315315

Un lambda peut être mis en œuvre à l'aide d'une fermeture, mais il n'est pas nécessairement en soi une fermeture.

Une fermeture est "une fonction avec un référencement de l'environnement pour les non-variables locales de la fonction.".

Lorsque vous effectuez une expression lambda qui utilise les variables définies à l'extérieur de la méthode, le lambda doit être mis en œuvre à l'aide d'une fermeture. Par exemple:

int i = 42;

Action lambda = () => { Console.WriteLine(i); }; 

Dans ce cas, le compilateur a généré méthode doit avoir accès à la variable (i) définies dans un tout autre portée. Pour ce travail, la méthode qu'il génère est une "fonction, ainsi que le référencement de l'environnement" - en gros, c'est la création d'une "fermeture" pour récupérer l'accès à la variable.

Cependant, cette lambda:

Action lambda2 = () => { Console.WriteLine("Foo"); }

Ne repose pas sur un "référencement environnement", puisque c'est un méthode. Dans ce cas, le compilateur génère une normale de la méthode statique, et il n'y a pas de fermeture impliqués à tous.

Dans les deux cas, le lambda est la création d'un delegate (fonction"objet"), mais c'est seulement à la création d'une fermeture dans le premier cas, que le lambda n'a pas nécessairement besoin de "capturer" le référencement de l'environnement dans tous les cas.

75voto

Eric Lippert Points 300275

Reed réponse est correcte; je voudrais simplement ajouter quelques détails supplémentaires:

  • les expressions lambda et les méthodes anonymes ont tous deux la fermeture de la sémantique, c'est qu'ils "capture" leur extérieur variables et de prolonger la durée de vie de ces variables.

  • fonction anonyme est le terme que nous utilisons pour désigner une expression lambda ou une méthode anonyme. Oui, c'est déroutant. Désolé. C'était le mieux que nous pouvions trouver.

  • une fonction qui peut être traitée comme un objet est juste un délégué. Ce qui fait un lambda d'une fermeture , c'est qu'il capte son externe variables.

  • les expressions lambda converti à l'expression des arbres ont également la fermeture de la sémantique, qui est assez intéressant. Et la mise en œuvre correctement a été une douleur dans le cou, je vous dis!

  • "ce" est considéré comme un "extérieur variable" aux fins de la création d'une fermeture, même si "ce" n'est pas une variable.

12voto

Jason Points 125291

C'est de la "fermeture" de ne pas "clojure."

Ce n'est pas ce que la fermeture est. Une fermeture est essentiellement une représentation d'une fonction, ainsi que toute non-variables locales de la fonction consomme.

En ce sens, les lambdas ne sont pas des fermetures, mais ils ne provoquer des fermetures d'être généré par le compilateur si ils se refermer sur toutes les variables.

Si vous utilisez ILDASM sur un assembly qui contient un lambda qui se ferme sur certaines variables, vous le verrez dans cette assemblée un générés par le compilateur classe qui repsresents la fonction et les variables qui ont été fermés. C' est la fermeture.

Quand vous dites

les fonctions qui sont traitées comme des objets,

c'est normalement juste la fonction "objet" (en C#, nous disions "délégué") et est commun dans la programmation fonctionnelle.

8voto

usr Points 74796

Oui. Les fermetures capturent généralement les variables de l'étendue externe. Lambdas peut le faire. Cependant, si votre lambda ne capture rien, il ne s'agit pas d'une fermeture.

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