AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Datentyp für anonyme Methoden wie TMethod für Methoden
Thema durchsuchen
Ansicht
Themen-Optionen

Datentyp für anonyme Methoden wie TMethod für Methoden

Ein Thema von RSE · begonnen am 8. Aug 2012 · letzter Beitrag vom 9. Aug 2012
Antwort Antwort
RSE

Registriert seit: 26. Mär 2010
254 Beiträge
 
Delphi XE Enterprise
 
#1

Datentyp für anonyme Methoden wie TMethod für Methoden

  Alt 8. Aug 2012, 11:41
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!
"Seit er seinen neuen Computer hat, löst er alle seine Probleme, die er vorher nicht hatte."
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#2

AW: Datentyp für anonyme Methoden wie TMethod für Methoden

  Alt 8. Aug 2012, 11:51
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 tmytype = reference to ...; 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.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
RSE

Registriert seit: 26. Mär 2010
254 Beiträge
 
Delphi XE Enterprise
 
#3

AW: Datentyp für anonyme Methoden wie TMethod für Methoden

  Alt 8. Aug 2012, 12:31
Das Problem ist ja, daß die Parameter-Definition da nicht mit abgelegt wird, weswegen einem sowieso eine allgemeine Variable nicht hilft.
Ich habe eine Abstraktion, die das Array verwaltet, dort sind die Parameter egal, dort brauche ich diese allgemeine Variable. Dann habe ich eine Konkretisierung, die dem Nutzer sichtbar ist und somit den Typ des zu registrierenden Handlers prüft (also die Parameter) und den Aufruf der Handler übernimmt - die zweite und letzte Stelle, an der die Parameter bekannt sein müssen.

Du kannst dir also nur mit tmytype = reference to ...; 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.
Das gleicht ja der Definition einer normalen "procedure of object"-Deklaration, die es neben TMethod auch noch gibt. Ist für mich in der Konkretisierung relevant, aber für die abstraktere Ebene nach meinem Wissensstand unbrauchbar. Oder kann man jede beliebige Referenz gefahrlos auf "TRef = reference to procedure;" casten?

Folgender Code ist compilierbar und wird scheinbar korrekt ausgeführt:
Delphi-Quellcode:
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;
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...
"Seit er seinen neuen Computer hat, löst er alle seine Probleme, die er vorher nicht hatte."
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#4

AW: Datentyp für anonyme Methoden wie TMethod für Methoden

  Alt 8. Aug 2012, 12:47
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.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 8. Aug 2012 um 13:05 Uhr)
  Mit Zitat antworten Zitat
RSE

Registriert seit: 26. Mär 2010
254 Beiträge
 
Delphi XE Enterprise
 
#5

AW: Datentyp für anonyme Methoden wie TMethod für Methoden

  Alt 8. Aug 2012, 13:31
Da würde ich eher empfehlen das Konzept zu überdenken und lieber typsicher zu bleiben, unter der Verwendung mehrerer Variablen, anstatt einer Zusammengemanschten.
Das ist durch die Konkretisierung gegeben. Ich möchte aber Codevervielfältigung durch die Abstraktion verhindern, und da stören die Typinfos eher. Sie gehen aber nicht verloren.
"Seit er seinen neuen Computer hat, löst er alle seine Probleme, die er vorher nicht hatte."
  Mit Zitat antworten Zitat
RSE

Registriert seit: 26. Mär 2010
254 Beiträge
 
Delphi XE Enterprise
 
#6

AW: Datentyp für anonyme Methoden wie TMethod für Methoden

  Alt 9. Aug 2012, 08:53
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...
"Seit er seinen neuen Computer hat, löst er alle seine Probleme, die er vorher nicht hatte."
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#7

AW: Datentyp für anonyme Methoden wie TMethod für Methoden

  Alt 9. Aug 2012, 09:30
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.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
RSE

Registriert seit: 26. Mär 2010
254 Beiträge
 
Delphi XE Enterprise
 
#8

AW: Datentyp für anonyme Methoden wie TMethod für Methoden

  Alt 9. Aug 2012, 10:26
Wenn ich einen Event Registriere, dann übergebe ich den Handler an eine Register-Methode:
OnChangeRegister(ChangeHandler); .

Möchte ich den Event dann nicht mehr empfangen, dann rufe ich folgendes auf:
OnChangeUnRegister(ChangeHandler); .

Dabei sind verschiedene Fälle zu unterscheiden:
  1. ChangeHandler ist eine Prozedur/Funktion/Methode:
    Hier wird beim Aufruf von OnChangeUnRegister eine neue Closure erzeugt und somit der Handler nicht gefunden, um ihn zu entfernen. (ungetestet)
  2. ChangeHandler ist eine anonyme Methode:
    Hierzu müsste ich mir die anonyme Methode in einer Variable gemerkt haben, dann sollte das wohl klappen, wenn mit dem "="-Operator verglichen wird. Andernfalls müsste ich sicherstellen, dass der Handler mindestens so lange Sinn macht (auf nichts zwischenzeitlich freigegebenes zugreift), wie das Objekt mit dem Event existiert.
Insgesamt ist mir die Sache mit den Referenzen für diesen Einsatzzweck zu undurchsichtig auch in der Anwendung. Es gibt zu viel zu beachten bezüglich Gleichheit und Gültigkeit der Handler und beteiligten Objekte. Ich belasse es bei Handlern vom Typ TMethod. Dabei habe ich geringfügige Einschränkungen gegenüber Referenzen, aber das ganze bleibt performanter und durchsichtiger.
"Seit er seinen neuen Computer hat, löst er alle seine Probleme, die er vorher nicht hatte."
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#9

AW: Datentyp für anonyme Methoden wie TMethod für Methoden

  Alt 9. Aug 2012, 10:36
Das geht eben nicht.
PS: Genau das war das Problem, welches ich damals auch hatte ... registrieren von Events und das deregistrieren.

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);
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:13 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz