C# : Petit gag avec les méthodes anonymes
J'utilise les méthodes anonymes depuis que j'ai VS 2005. Pourtant tout à l'heure je me suis demandé comment fonctionnait précisément l'accès aux variables définies à l'exterieur du délégué. Par exemple lorsque vous faites ça (avec la variable x) :
int x = 0;
Action<string> del = delegate(string s)
{
Console.WriteLine(s + " " + x.ToString());
};
En cherchant des détails sur Internet je me suis rendu compte que ce n'était pas si intuitif que ça, regardez ces 2 programmes :
delegate void Foo();
public static void Main()
{
List<Foo> myFuncs = new List<Foo>();
for(int i = 0; i < 3; i++)
{
int x = i*2;
Foo anonFunc = delegate
{
Console.WriteLine("x == {0}", x);
};
myFuncs.Add(anonFunc);
}
foreach(Foo anonFunc in myFuncs)
anonFunc();
}
Celui là produit la sortie suivante :
x == 0
x == 2
x == 4
En faisant une légère modification au programme :
delegate void Foo();
public static void Main()
{
List<Foo> myFuncs = new List<Foo>();
int x;
for(int i = 0; i < 3; i++)
{
x = i*2;
Foo anonFunc = delegate
{
Console.WriteLine("x == {0}", x);
};
myFuncs.Add(anonFunc);
}
foreach(Foo anonFunc in myFuncs)
anonFunc();
}
On a alors le résultat suivant :
x == 4
x == 4
x == 4
Ceci est dû au fait que lorsqu'on utilise des variables externes à la méthode anonyme, celles-ci sont comme passées par référence. Dans le 1er programme on a une référence différente à chaque passage de la boucle puisque on passe sur l'instruction int x à chaque passage, alors que dans le 2e cas, c'est toujours la même variable qui est passée par référence.
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :