Lassen Sie mich im Voraus entschuldigen - ich bin wahrscheinlich Schlachter die Terminologie. Ich habe ein vages Verständnis davon, was eine Schließung ist, kann aber das Verhalten, das ich sehe, nicht erklären. Zumindest denke ich, dass es ein Schließungsproblem ist. Ich habe online gesucht, aber nicht die richtigen Keywords gefunden, um zu bekommen, was ich möchte.Warum sind einige Verschlüsse "freundlicher" als andere?
Genauer gesagt - ich habe zwei Blöcke Code, die wirklich ähnlich sind (zumindest für meine Augen). Erstens:
static void Main(string[] args)
{
Action x1 = GetWorker(0);
Action x2 = GetWorker(1);
}
static Action GetWorker(int k)
{
int count = 0;
// Each Action delegate has it's own 'captured' count variable
return k == 0 ? (Action)(() => Console.WriteLine("Working 1 - {0}",count++))
: (Action)(() => Console.WriteLine("Working 2 - {0}",count++));
}
Wenn Sie diesen Code ausführen, und rufen x1() und x2() Sie werden sehen, dass sie einen separaten ‚count‘ Wert zu halten.
foreach(var i in Enumerable.Range(0,4))
{
x1(); x2();
}
Ausgänge:
Working 1 - 0
Working 2 - 0
Working 1 - 1
Working 2 - 1
Working 1 - 2
Working 2 - 2
Working 1 - 3
Working 2 - 3
Das macht Sinn für mich und stimmt mit den Erklärungen ich gelesen habe. Hinter den Kulissen wird für jeden Delegierten/jede Aktion eine Klasse erstellt und der Klasse wird ein Feld zugewiesen, in dem der Wert von "count" gespeichert wird. Ich ging ins Bett und fühlte mich schlau!
aber dann - ich versuchte, diesen sehr ähnlichen Code:
// x3 and x4 *share* the same 'captured' count variable
Action x3 =() => Console.WriteLine("Working 3 - {0}", count++);
Action x4 =() => Console.WriteLine("Working 4 - {0}", count++);
Und (wie der Kommentar sagt) das Verhalten ist hier völlig anders. x3() und x4() scheinen den gleichen Zählwert zu haben!
Working 3 - 0
Working 4 - 1
Working 3 - 2
Working 4 - 3
Working 3 - 4
Working 4 - 5
Working 3 - 6
Working 4 - 7
ich kann sehen, was passiert - aber ich weiß nicht wirklich, warum sie anders behandelt werden. In meinem Kopf - ich mochte dieses ursprüngliche Verhalten, das ich sah, aber das spätere Beispiel verwirrt mich. Ich hoffe das ergibt Sinn. Danke
Ihr erstes Beispiel hatte zwei verschiedene 'int count'-Variablendeklarationen (aus den separaten Methodenaufrufen).Ihr zweites Beispiel teilt die _Same_Variablen-Deklaration. Ihr erstes Beispiel würde sich genauso verhalten wie das zweite Beispiel, bei dem "int count" ein Feld Ihres Hauptprogramms war. –