![]() |
Datentyp für anonyme Methoden wie TMethod für Methoden
Hallo,
ich verwende für Multicast-Events momentan ein array of TMethod. Damit kann ich die ganze Verwaltung (Register, Unregister, Verhinderung von Doppelregistrierungen etc.) mit den selben Codeteilen durchführen. Lediglich der Aufruf muss natürlich für jeden Event speziell geschrieben werden, da ja immer andere Parameter auftauchen. Problem: Bei diesem Vorgehen kann ich nur Methoden als Event-Handler verwenden, keine Funktionen, Prozeduren und vor allem keine anonymen Methoden. Ich möchte gerne ein array of "Referenz" nutzen, damit ich auch anonyme Methoden benutzen kann. Ich suche also einen Referenz-Ersatz für TMethod. Nun habe ich etwas geforscht und gefunden, dass hinter einer "Referenz" letztlich ein Interface und ein ganzes Objekt mit einer entsprechenden Invoke-Methode steht. Das ganze ist mit Referenzzählung ausgestattet. Diese Referenzzählung soll natürlich unterstützt werden, ich möchte nicht daneben noch referenzgezählte Variablen halten müssen, damit ich beim Aufruf nicht ins leere greife (das dahinterliegende Objekt bereits freigegeben ist). IInterface ist der Vorfahr aller referenzgezählten Interfaces, aber natürlich in keiner Weise zuweisungskompatibel mit einer Referenzvariable. Wer hat eine Idee, wie mein Vorhaben umsetzbar ist? Ich möchte allerdings keinen Hack! Also ich werde mir nicht die Code-Einsprungadresse holen mit dem Wissen, dass diese momentan an der vierten Stelle des Objektes gespeichert ist (nach _AddRef usw.). MfG RSE p.s. Bitte nicht mit den unterschiedlichen Bedeutungen von "Referenz" in Referenzvariable ("Zeiger" auf eine anonyme Methode) und Referenzzählung (Anzahl der Zeiger auf ein Objekt) durcheinanderkommen! Wer dafür bessere Bezeichnungen weiß, bitte gern her damit! |
AW: Datentyp für anonyme Methoden wie TMethod für Methoden
Interface.
Tut mir Leid, aber genauer kann man es nicht beschreiben, daß die interne Verwaltung quasi geheimgehalten wird, aber ich hab inzwischen rausgefunden, daß alles von einem generischen Interface gemacht wird. Das Problem ist ja, daß die Parameter-Definition da nicht mit abgelegt wird, weswegen einem sowieso eine allgemeine Variable nicht hilft. Du kannst dir also nur mit
Delphi-Quellcode:
eine variable erstellen, welche für einen bestimmte Parameterdeklaration gilt, egal ob für eine anonyme Methode, ein "normale" Methode oder eine Funktion/Prozedur ... das passt alles da rein, solange die Parameter übereinstimmen.
tmytype = reference to ...;
|
AW: Datentyp für anonyme Methoden wie TMethod für Methoden
Zitat:
Zitat:
Folgender Code ist compilierbar und wird scheinbar korrekt ausgeführt:
Delphi-Quellcode:
Funktioniert hier die Referenzzählung noch korrekt? Wird das dahinterliegende Objekt nicht "beschädigt"? Oder funktioniert obiger Quellcode nur zufällig? Mein Wissen über Interfaces ist auch erst wenige Wochen alt und beschränkt sich auf die Basics...
procedure TMyForm.DoShow;
type TRef = reference to procedure; TTestRef = reference to function(i: Integer): string; var s: string; r: TRef; t: TTestRef; begin t := function (i: Integer): string begin Result := IntToStr(i); end; r := TRef(t); s := TTestRef(r)(20); showmessage(s); end; |
AW: Datentyp für anonyme Methoden wie TMethod für Methoden
Wie gesagt, allgemein ist Interface, aber da braucht man dann schon einen brutalen Cast, um es dahin zu bekommen.
Da würde ich eher empfehlen das Konzept zu überdenken und lieber typsicher zu bleiben, unter der Verwendung mehrerer Variablen, anstatt einer Zusammengemanschten. |
AW: Datentyp für anonyme Methoden wie TMethod für Methoden
Zitat:
|
AW: Datentyp für anonyme Methoden wie TMethod für Methoden
Ich habe nun einen weiteren Test gemacht, der bestätigt, dass die Referenzzählung mit dieser Methode (cast auf reference to procedure) nicht durcheinandergebracht wird, zumindest wird die Referenz nicht frühzeitig freigegeben.
Allerdings habe ich für meinen Anwendungsfall (Multicast-Events) ein anderes Problem, an dem die Sache scheitert: Referenzen lassen sich nicht vergleichen wie Methodenzeiger, da es Closures sind (sie beinhalten die benutzten Variablen aus dem Scope und zu der Zeit, wo und als die Referenz erstellt wurde). Damit kann ich sie nicht mehr aus der Menge der Event-Handler entfernen, da ich sie nicht wiederfinde. Ich könnte höchstens bei der Registrierung für den Event einen Index zurückgeben, aber das ist insgesamt aufwendiger als Methoden als Handler zu verwenden... |
AW: Datentyp für anonyme Methoden wie TMethod für Methoden
Nein, die lassen sich nicht vergleichen, weil ständig neue Interface-Instanzen erstellt werden. (dazu gibt es von mir auch schon ein paar Threads)
Wenn man sich das erstellte Interface merkt, dann kann man es auch wieder vergleichen, aber bei jeder neuen Zuweisung (außer von eine ReferenceTo-Variable) wird ein neues Interface erstellt. Und bei Interfaces kannst du nunmal nur den Interface-Zeiger vergleichen, da man den Inhalt nicht kennt. OK, wenn lokale Variablen in eine anonyme Methode aufgenommen werden, wann muß man zwangsläufig auch jedesmal ein neues Interface erstellen lassen, welches auf die aktuellen Variablen zeigt. |
AW: Datentyp für anonyme Methoden wie TMethod für Methoden
Wenn ich einen Event Registriere, dann übergebe ich den Handler an eine Register-Methode:
Delphi-Quellcode:
.
OnChangeRegister(ChangeHandler);
Möchte ich den Event dann nicht mehr empfangen, dann rufe ich folgendes auf:
Delphi-Quellcode:
.
OnChangeUnRegister(ChangeHandler);
Dabei sind verschiedene Fälle zu unterscheiden:
|
AW: Datentyp für anonyme Methoden wie TMethod für Methoden
Das geht eben nicht.
PS: Genau das war das Problem, welches ich damals auch hatte ... registrieren von Events und das deregistrieren. :zwinker: Wenn ChangeHandler eine Methode ist, dann mußt du daraus erstmal ein Interface erstellen, und dieses dir speichern. Mit dem gespeichertem Wert kannst du es dann auch wieder suchen/deregistrieren.
Delphi-Quellcode:
var save: reference to ...;
save := ChangeHandler; OnChangeRegister(save); OnChangeUnRegister(save); |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:44 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz