2010-11-24 6 views
0

Le programme suivantPourquoi les événements se comportent différemment dans ce cas?

static IEnumerable<Action> Create() 
{ 
    foreach (var i in Enumerable.Range(0, 2)) 
    { 
     yield return() => { Console.Write(i); }; 
    } 
} 

static void Main(string[] args) 
{ 
    foreach (var func in Create()) 
    { 
     func(); 
    } 

    Console.ReadLine(); 
} 

Ouputs

Ce programme

static event Action SomethingHappened; 

static void Register() 
{ 
    foreach (var i in Enumerable.Range(0, 2)) 
    { 
     SomethingHappened +=() => { Console.Write(i); }; 
    } 
} 

static void Main(string[] args) 
{ 
    Register(); 
    SomethingHappened(); 
    Console.ReadLine(); 
} 

sorties

Pourquoi est-ce donc? Comment rendre le programme 2 sortie 01?

Répondre

3

Vous capturez la variable de boucle dans votre expression lambda. Cela signifie que lorsque le délégué est finalement appelé, il utilisera la dernière valeur de la variable ... qui sera toujours 1. Essayez ceci:

foreach (var i in Enumerable.Range(0, 2)) 
{ 
    int copy = i; 
    SomethingHappened +=() => { Console.Write(copy); }; 
} 

... puis lire Eric Lippert's blog post à ce sujet.

1

Dans le deuxième programme, la variable i est capturée par le lambda. Pour obtenir le comportement correct, faites une copie locale avant de l'utiliser dans le lambda. Par exemple.

foreach (var i in Enumerable.Range(0, 2)) 
{ 
    var local = i; 
    SomethingHappened +=() => { Console.Write(local); }; 
} 
Questions connexes