Local des fonctions en C# sont intelligents en termes de capture - au moins dans le Roslyn mise en œuvre. Quand le compilateur est capable de garantir que vous n'êtes pas de la création d'un délégué de la fonction locale (ou faire autre chose qui permettra de prolonger la durée de vie de la variable) il peut utiliser ref
paramètre avec toutes les saisies de variables dans une générés struct pour communiquer avec la fonction local. Par exemple, votre deuxième méthode finirait en tant que quelque chose comme:
public int MultiplyFoo(int id)
{
__MultiplyFoo__Variables variables = new __MultiplyFoo__Variables();
variables.id = id;
return __Generated__LocalBar(ref variables);
}
private struct __MultiplyFoo__Variables
{
public int id;
}
private int __Generated__LocalBar(ref __MultiplyFoo__Variables variables)
{
return variables.id * 2;
}
Donc, il n'y a pas d'allocation de tas nécessaire qu'il y en aurait pour (dire) d'une expression lambda converti à un délégué. D'autre part, il y a la construction de la structure, puis de copier les valeurs dans la. Si le passage d'un int
, en valeur, est plus ou moins efficace que le passage de la structure par la référence est peu probable d'être important... bien que je pense que dans le cas où vous avez eu une énorme structure comme une variable locale, cela voudrait dire que l'utilisation implicite de capture serait plus efficace que la simple utilisation d'un paramètre de valeur. (Même si votre fonction local utilisé beaucoup de la capture de variables locales.)
La situation déjà devient plus compliqué lorsque vous avez plusieurs variables locales d'être capturé par les différentes fonctions locales - et encore plus quand certains de ceux qui sont des fonctions locales dans les boucles etc. Explorer avec ildasm
ou un Réflecteur, etc peuvent être assez divertissant.
Dès que vous commencez à faire quelque chose de compliqué, comme l'écriture de méthodes asynchrones, itérateur, les blocs, les expressions lambda au sein de l'fonctions locales, l'aide de la méthode du groupe de conversions pour créer un délégué de la fonction locale, etc... à ce stade, je n'hésiterais pas à continuer de le deviner. Vous pouvez soit essayer de référence le code dans chaque sens, ou de regarder le IL, ou tout simplement écrire selon le code est plus simple et comptons sur votre plus grande performance des tests de validation (qui, vous l'avez déjà? :) pour vous permettre de savoir si c'est un problème.