Gibt es in C # eine Möglichkeit, einen Funktionsaufruf zum späteren Aufruf zu speichern? Zum Beispiel möchte ich sagen können:
%Vor%Lass mich dir einen Kontext geben: Ich erstelle ein Spiel in XNA und ich möchte eine DelayedFunctionCaller-Klasse erstellen, auf die jedes Objekt verweisen kann, um komplette Funktionsaufrufe abzuwickeln, zusammen mit einer Wartezeit bis zum Aufruf die Funktion. Ich kümmere mich um die gesamte Zeit - ich warte und triggert mich selbst, damit ich nicht verloren bin. Ich bin mir nicht sicher, wie oder wie ich die Funktion richtig verpacke, damit sie an den DelayedFunctionCaller weitergeleitet wird.
Hier ist der Kicker: Der DelayedFunctionCaller muss in der Lage sein, jede Funktion auszuführen, egal, welches Objekt ihm eine Funktion sendet, was die Funktion zurückgibt oder welche Parameter sie benötigt **. Ich habe bereits über 100 Klassen in meinem Spiel, und das Ziel ist es, ein Objekt zu erstellen, das jeden Funktionsaufruf von einem beliebigen von ihnen speichern kann, um später anzurufen.
Aus meinen eigenen Recherchen habe ich die Type
-Klasse gefunden und ich weiß, dass ich den Typ des aufrufenden Objekts speichern kann, den Funktionsnamen als Zeichenfolge (was ein akzeptables Opfer ist), dann verwende GetMethod()
, um die Methode in MemberInfo
zu speichern, dann verwenden Sie MemberInfo
's Invoke()
, um die Funktion aufzurufen, auch für ein gespeichertes Objekt und mit den Parametern (als Array von Objects
).
Aber das scheint alles sehr ... hack-ish. Ich habe versucht, das einmal nachzulesen und dachte, dass Generic Delegates der Weg war, den ich gehen wollte, aber ich habe mich so verloren, dass ich aufgegeben habe. Bin ich auf dem richtigen Weg? Ist das der einzige Weg, dies zu tun? Was ist mit Generic Delegates, oder war ich gerade verrückt, als ich dachte, es würde mein Problem lösen?
Jede und jede Hilfe wird geschätzt. Danke!
Sie können es als Aktion speichern, indem Sie einen Lambda-Ausdruck verwenden:
%Vor% Wenn die Funktion etwas zurückgibt und Sie ihren Wert benötigen, verwenden Sie stattdessen den Typ Func<T>
.
Beachten Sie, dass jede Variable, die Sie innerhalb des Lambda verwenden, selbst erfasst wird, nicht ihr Wert; Wenn sich der Wert ändert, ist dies der Wert, der beim Aufruf der Funktion verwendet wird. Siehe Eric Lippert 's Blog für eine tiefere Erklärung.
Zusätzlich zu Lambda-Ausdrücken können Sie auch die Methoden IEnumerable
oder IEnumerable<T>
verwenden. Nachdem Methoden aufgerufen werden, verwenden Sie jede Anweisung. Beispiel: Dieser Unity-Engine-Code: