Sie müssen mit den Implementierungsdetails für method pointers und schmutzig gehen. Diese werden als sogenannter Doppelzeiger Wert gespeichert. Ein Zeiger für das Objekt des Methodenaufrufs (die Instanz) und ein Zeiger für die Methode selbst (der Code).
Sie können den Typ TMethod
aus der Einheit System
verwenden, um Methodenzeiger darzustellen. Seine Erklärung sieht so aus (mit den Vergleichsoperator für Einfachheit entfernt):
type
TMethod = record
Code, Data: Pointer;
end;
Sie benötigen eine Typumwandlung verwenden Zuordnungen zwischen diesen Typen zu machen:
uses
System.Classes;
var
Event: TNotifyEvent;
Method: TMethod;
begin
Method := TMethod(Event);
TMethod(Event) := Method;
end.
Offensichtlich nichts davon ist typsicher Sie müssen also auf Korrektheit achten. Der Compiler kann Ihnen nicht helfen. Es gibt nichts wie den Konvertierungsoperator "checked type", as
, um mit Methodenzeigern zu arbeiten. Das heißt, dass Sie bei der Umwandlung von TMethod
in einen bestimmten Methodenzeigertyp darauf achten müssen, dass die TMethod
-Instanz wirklich eine Instanz des Methodenzeigers ist, in den Sie einwerfen. Stellen Sie sich diesen Vorgang so vor, als würde er von einem getippten Zeiger auf einen nicht typisierten Zeiger umwandeln und dann wieder zurück.
Nun, wenn Sie willkürlich Methodenzeiger in TMethod
Instanzen speichern möchten, ist das in Ordnung. Was passiert aber, wenn Sie diese Methoden später auslösen müssen? Sie müssen wissen, welcher Typ von Methodenzeiger wirklich hinter jeder TMethod
Instanz steht. Damit Sie wissen, wie Sie es umsetzen, welche Argumente es benötigt und wie Sie es nennen. Das bedeutet, dass Sie neben der eigentlichen Methode zusätzliche Informationen über den wahren Typ der Methode speichern müssen.
Also ich denke, dass ich vielleicht die Frage beantwortet habe, die du gestellt hast, aber ich bin mir nicht sicher, dass es dir von großem Nutzen sein wird. Um zu verstehen, dass wir wirklich mehr darüber wissen müssen, was Sie erreichen wollen und welche Informationen Sie wann haben. Wenn Sie beispielsweise die Argumente kennen, die an die Methode zu dem Zeitpunkt übergeben werden sollen, an dem Sie sie speichern müssen, können Sie die Variable erfassen und in eine anonyme Methode umbrechen. Das würde dir erlauben, die Typensicherheit beizubehalten und irgendwelche der eher zweifelhaften Modelle, die ich oben demonstriere, zu vermeiden. Vielleicht benötigen Sie partial application, um Ihre inhomogenen Methodenzeiger so anzupassen, dass sie dieselbe Schnittstelle haben. In diesem Fall können wieder anonyme Methoden helfen.
Können Sie als Beispiel angeben, was Sie zu tun versuchen. Im Moment sieht es so aus, als ob Sie versuchen, sich in den Fuß zu schießen, indem Sie Methoden aufrufen, ohne alle erforderlichen Parameter anzugeben. – Johan
Ich glaube, Sie sind in der falschen Annahme, dass "Prozedur (Absender: TObject) von Objekt" und "Prozedur (Absender: TObject; xyz: TSomehting) von Objekt" irgendwie kompatibel sind. Sie sind nicht! Wenn Sie beim Aufruf nicht die richtige Signatur haben, werden Sie die falschen Parameter übergeben, die mit einem Fehler enden. – Johan
Ich würde gerne eine Lösung mit Generika vorschlagen. Aber ich habe nicht genug Informationen, um eine vollständige Antwort zu formulieren. Versuchen Sie eine TList zu erstellen, die Sie dann anrufen können; ist das, was du versuchst zu tun? Wenn ja, habe ich eine einfache Antwort für dieses Problem. –
Johan