2009-07-16 10 views
4

Ich bin neugierig zu wissen, ob ein Lambda (wenn als Delegat verwendet wird) eine neue Instanz jedes Mal erstellen wird, wenn es aufgerufen wird, oder ob der Compiler einen Weg findet, den Delegaten nur einmal instanziieren und übergeben.Erstellt ein Lambda bei jedem Aufruf eine neue Instanz?

Genauer gesagt, ich möchte eine API für ein XNA-Spiel erstellen, die ich ein Lambda verwenden kann, um in einem benutzerdefinierten Rückruf zurückgeben. Da dies in der Update-Methode (die viele Male pro Sekunde aufgerufen wird) aufgerufen wird, wäre es ziemlich schlecht, wenn es jedes Mal eine Instanz neu erzeugt, um den Delegaten weiterzuleiten.

InputManager.GamePads.ButtonPressed(Buttons.A, s => s.MoveToScreen<NextScreen>()); 
+5

FYI, Sie können ildasm oder andere Dekompilationswerkzeuge verwenden, um den generierten Code zu betrachten. Wenn Sie dies tun, werden Sie feststellen, dass in diesem Fall der Delegat einmal generiert und in einem statischen Feld zwischengespeichert und dann jedes Mal erneut verwendet wird, wenn dieser Codepfad erreicht wird. Wenn das Lambda den Verweis "this" oder eine äußere Variable verwendet, hängt der Delegat von seiner Schließung ab und muss jedes Mal neu erstellt werden, wenn eine neue Abschlussumgebung benötigt wird. –

Antwort

2

Ja, es wird sie zwischenspeichern, wenn es folgende Möglichkeiten:

using System; 

class Program { 
    static void Main(string[] args) { 
     var i1 = test(10); 
     var i2 = test(20); 
     System.Console.WriteLine(object.ReferenceEquals(i1, i2)); 
    } 

    static Func<int, int> test(int x) { 
     Func<int, int> inc = y => y + 1; 
     Console.WriteLine(inc(x)); 
     return inc; 
    } 
} 

Es schafft ein statisches Feld, und wenn es null ist, füllt sie mit einem neuen Delegierten, sonst gibt die Delegierten.

Ausgänge 10, 20, wahr.

3

Ich war an Ihrer Frage interessiert, weil ich gerade angenommen hatte, dass diese Art von Sache immer ein neues Objekt erzeugen und daher in Code vermieden werden würde, der häufig genannt wird.

Ich mache etwas ähnliches, also dachte ich, ich würde ildasm verwenden, um herauszufinden, was genau hinter den Kulissen vor sich geht. In meinem Fall stellte sich heraus, dass jedes Mal, wenn der Delegat aufgerufen wurde, ein neues Objekt erstellt wurde. Ich poste meinen Code nicht, weil er ziemlich komplex und aus dem Zusammenhang heraus nicht einfach zu verstehen ist. Dies widerspricht der Antwort von MichaelGG, ich vermute, dass er in seinem Beispiel statische Funktionen nutzt. Ich würde vorschlagen, dass Sie es selbst ausprobieren, bevor Sie alles auf eine Art und Weise entwerfen und später herausfinden, dass Sie ein Problem haben. Ildasm ist der Weg zu gehen (http://msdn.microsoft.com/en-us/library/f7dy01k1.aspx), halte Ausschau nach irgendwelchen "newobj" Zeilen, du willst diese nicht.

Es lohnt sich auch, das CLR-Profil zu verwenden, um herauszufinden, ob Ihre Lambda-Funktionen Speicher zuordnen (http://www.microsoft.com/downloads/details.aspx?familyid=A362781C-3870-43BE-8926-862B40AA0CD0&displaylang=en). Es sagt, es ist für Framework 2.0, aber es funktioniert auch für 3.5 und es ist die neueste Version, die verfügbar ist.

Verwandte Themen