2016-12-31 4 views
1

Für ein Spiel, in dem Sie Ihre eigene KI codieren müssen, muss ich verschiedene Methodenaufrufe mit Parametern in die Warteschlange stellen. Zum Beispiel:Enqueue verschiedene Methodenaufrufe mit Parametern

MessageReceived(string text, Source source); 
MiningCompleted(ResourceData data); 

Dies getan werden muss, um alle Ereignisse zu Beginn des nächsten Schritts des Spiels und nicht sofort zu rufen.

namespace LambdaTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Queue<Action> q = new Queue<Action>(); 

      for (int i = 0; i < 5; i++) 
      { 
       q.Enqueue(new Action(() => { 
        // Methods should be called here 
        Console.WriteLine(i); 
       })); 
      } 

      foreach (Action a in q) 
       a(); 

      Console.ReadLine(); 
     } 
    } 
} 

Der erste Gedanke war es arbeiten muss: Jetzt habe ich eine kleine für Übergabe von Parametern an die Methoden nachweisen-of-Concept geschrieben. Nachdem ich die Ausgabe von 5x5 gesehen habe, war meine Frage, warum gibt es nicht 0 bis 4 aus und warum funktioniert es wirklich, weil i in diesem Bereich nicht mehr existiert.

  1. Warum gibt es 5x5 aus?
  2. Wie kann ich auf diese Weise verschiedene Methodenaufrufe mit Parametern einreihen?
+0

Was dies mit LINQ zu tun hat? (Was Sie im Grunde sehen, ist die Lebensdauer von 'i', die erweitert wird, bis alle anonymen Funktionen, die sie erfasst haben, für die Garbage Collection geeignet sind.) –

+0

Ist nicht() => {} linq? – Steven

+0

Nein, es handelt sich um Lambda-Ausdrücke, die zur selben Zeit wie LINQ eingeführt und in * LINQ stark verwendet werden, aber sie sind nicht Teil von LINQ. –

Antwort

1

Es gibt 5 fünfmal weil durch die Zeit, die möglichen Aktionen sind die Ausführung i ist 5. Es gibt nur ein einziges i Variable, und seine Lebensdauer verlängert wird, bis alle anonymen Funktionen, die sie berechtigt sind für Müll eingefangen Sammlung.

Um dies zu beheben, stellen nur eine separate Variable innerhalb der Schleife, die eine Kopie der Schleifenvariable nimmt:

for (int i = 0; i < 5; i++) 
{ 
    // Declared *inside* the loop, so each iteration will have a separate variable 
    int copy = i; 
    q.Enqueue(() => Console.WriteLine(copy)); 
}