Je regarde les nouvelles implémentations en C # 7.0 et je trouve intéressant qu'elles aient implémenté des fonctions locales mais je ne peux pas imaginer un scénario où une fonction locale serait préférée à une expression lambda, et quelle est la différence entre les deux.
Je comprends que les lambdas sont des anonymous
fonctions alors que les fonctions locales ne le sont pas, mais je ne peux pas comprendre un scénario du monde réel, où la fonction locale a des avantages par rapport aux expressions lambda
Tout exemple serait très apprécié. Merci.
Réponses:
Cela a été expliqué par Mads Torgersen dans C # Design Meeting Notes où les fonctions locales ont été abordées pour la première fois :
Pour approfondir encore, les avantages sont:
Performance.
Lors de la création d'un lambda, un délégué doit être créé, ce qui est une allocation inutile dans ce cas. Les fonctions locales ne sont en réalité que des fonctions, aucun délégué n'est nécessaire.
En outre, les fonctions locales sont plus efficaces pour capturer les variables locales: les lambdas capturent généralement des variables dans une classe, tandis que les fonctions locales peuvent utiliser une structure (passée à l'aide de
ref
), ce qui évite à nouveau une allocation.Cela signifie également que l'appel des fonctions locales est moins cher et qu'elles peuvent être intégrées, augmentant éventuellement encore davantage les performances.
Les fonctions locales peuvent être récursives.
Les lambdas peuvent également être récursifs, mais cela nécessite un code maladroit, où vous affectez d'abord
null
à une variable de délégué, puis au lambda. Les fonctions locales peuvent naturellement être récursives (y compris mutuellement récursives).Les fonctions locales peuvent être génériques.
Les lambdas ne peuvent pas être génériques, car ils doivent être affectés à une variable avec un type concret (ce type peut utiliser des variables génériques de la portée externe, mais ce n'est pas la même chose).
Les fonctions locales peuvent être implémentées sous forme d'itérateur.
Lambdas ne peut pas utiliser le mot-clé
yield return
(etyield break
) pour implémenter laIEnumerable<T>
fonction -returning. Les fonctions locales peuvent.Les fonctions locales sont plus belles.
Cela n'est pas mentionné dans la citation ci-dessus et pourrait être juste mon parti pris personnel, mais je pense que la syntaxe de fonction normale semble meilleure que d'assigner un lambda à une variable de délégué. Les fonctions locales sont également plus succinctes.
Comparer:
la source
Func<int, int, int> f = (x, y) => x + y; f(arg1:1, arg2:1);
.object
. Ainsi, lambdas pourrait utiliser une structure, mais elle devrait être encadrée, donc vous auriez toujours cette allocation supplémentaire.En plus de la bonne réponse de svick, il y a un autre avantage aux fonctions locales:
elles peuvent être définies n'importe où dans la fonction, même après l'
return
instruction.la source
#region Helpers
au bas de la fonction, afin d'éviter l'encombrement dans cette fonction et surtout éviter l'encombrement dans la classe principale.Si vous vous demandez également comment tester la fonction locale, vous devriez vérifier JustMock car il a la fonctionnalité pour le faire. Voici un exemple de classe simple qui sera testé:
Et voici à quoi ressemble le test:
Voici un lien vers la documentation JustMock .
Avertissement. Je suis l'un des développeurs responsables de JustMock .
la source
.DoNothing().OccursOnce();
Et affirmer plus tard que l'appel a été effectué en appelant laMock.Assert(foo);
méthode. Si vous souhaitez savoir comment d'autres scénarios sont pris en charge, vous pouvez lire notre article d'aide Asserting Occurrence .J'utilise des fonctions en ligne pour éviter la pression du ramasse-miettes en particulier lorsque je traite des méthodes plus longues. Supposons que l'on souhaite obtenir 2 ans ou des données de marché pour un symbole boursier donné. En outre, on peut emballer beaucoup de fonctionnalités et de logique métier si nécessaire.
ce que l'on fait est d'ouvrir une connexion socket au serveur et de boucler sur les données liant un événement à un événement. On peut y penser de la même manière qu'une classe est conçue, une seule n'écrit pas de méthodes d'assistance partout qui ne fonctionnent vraiment que pour une seule fonctionnalité. ci-dessous est un exemple de ce à quoi cela pourrait ressembler, veuillez noter que j'utilise des variables et que les méthodes "d'assistance" sont en dessous de la méthode. Dans le Enfin, je supprime joliment les gestionnaires d'événements, si ma classe Exchange était externe / injectée, je n'aurais aucun gestionnaire d'événements en attente enregistré
Vous pouvez voir les avantages mentionnés ci-dessous, ici vous pouvez voir un exemple d'implémentation. J'espère que cela aide à expliquer les avantages.
la source