Bonjour,

Je rencontre un comportement que je ne comprends pas. C'est probablement tout bête, mais si quelqu'un peut m'expliquer le pourquoi du comment histoire que je me couche moins bête ce soir

Soit les classes Item et OtherItem
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Item
{
    public Action Action { get; set; }
}
 
class OtherItem
{
    public event EventHandler Click = delegate { };
 
    public void ClickRequested()
    {
        Click(this, EventArgs.Empty);
    }
}
et le code suivant
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Program
{
    static void Main(string[] args)
    {
        Item item1 = new Item { Action = delegate { Console.WriteLine("Item 1"); } };
        Item item2 = new Item { Action = delegate { Console.WriteLine("Item 2"); } };
        Item item3 = new Item { Action = delegate { Console.WriteLine("Item 3"); } };
 
        List<Item> items = new List<Item> { item1, item2, item3 };
        List<OtherItem> otherItems = new List<OtherItem>();
 
        foreach (Item item in items)
        {
            OtherItem otherItem = new OtherItem();
            otherItem.Click += delegate { item.Action(); };
            otherItems.Add(otherItem);
        }
 
        foreach (OtherItem otherItem in otherItems)
        {                
            otherItem.ClickRequested();
        }
 
        Console.ReadLine();
    }
}
Alors que je m'attends à avoir très logiquement en sortie
Item 1
Item 2
Item 3
le code précédent affiche en réalité
Item 3
Item 3
Item 3
Si je modifie légèrement la première boucle foreach en stockant dans une variable l'objet énuméré
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
foreach (Item item in items)
{
    Item i = item;
    OtherItem otherItem = new OtherItem();
    otherItem.Click += delegate { i.Action(); };
    otherItems.Add(otherItem);
}
Le comportement est alors celui attendu

Bref, je ne suis pas sûr de comprendre le pourquoi de la chose. Est-ce lié à la capture de variable de la méthode anonyme ? Bien que je ne vois pas pourquoi.