![]() |
generische Callback-Liste erstellen ?
Ich wollte mir eine grundlegende Eventliste erstellen, also eine Liste womit Callbackprozeduren gespeichert werden und auch aufgerufen werden können.
Als "normale" Liste hab ich schon lange im Einsatz und da ich
Delphi-Quellcode:
Nun brauch ich grade in einen Projekt mehrere dieser Listen und dachte mir
// Ausschnitt mit den wichtigsten Headern und Funktionen
Type TEvent = Procedure(Sender: TMyObject) of Object; TCallback = Class FEventList: Array of TEvent; Procedure Add (Const Value: TEvent); Procedure Remove(Const Value: TEvent); Procedure Call (Sender: TSender); End; Procedure TCallback.Call(Sender: TSender); Var i: Integer; Begin For i := Count - 1 downto 0 do FEventList[i](Sender); End; "och, warum erstellst'e dir nicht einfach ein (generisches) Grundgerüst". So weit so gut ... die Deklaration funktioniert perfekt, aber das Aufrufen der Funktionen funktioniert einfach nicht.
Delphi-Quellcode:
// meine Deklaration
Type TInternalCallback<TProc> = Class(TList<TProc>) Procedure Add (Const Value: TProc); Procedure Remove(Const Value: TProc); End; TCallback<TProc, TSender> = Class(TInternalCallback<TProc>) Procedure Call(Const Sender: TSender); End; TCallback<TProc, TSender, TParam1> = Class(TInternalCallback<TProc>) Procedure Call(Const Sender: TSender; Const Param1: TParam1); End; TCallback<TProc, TSender, TParam1, TParam2> = Class(TInternalCallback<TProc>) Procedure Call(Const Sender: TSender; Const Param1: TParam1; Const Param2: TParam2); End; ...
Delphi-Quellcode:
// das Ganze etwas übersichtlicher (inkl. Markierung der Fehlerstelle)
Type TCallback<TProc, TSender> = Class(TList<TProc>) Procedure Add (Const Value: TProc); Procedure Remove(Const Value: TProc); Procedure Call (Sender: TSender); End; Procedure TCallback<TProc, TSender>.Call(Sender: TSender); Var i: Integer; Begin For i := Count - 1 downto 0 do Items[i](Sender); // ^ genau hier End; Zitat:
Delphi-Quellcode:
Und dieses geht auch nicht
For i := Count - 1 downto 0 do
TProc(Items[i])(Sender); // ^ genau hier
Delphi-Quellcode:
Type TCallback<TProc: Procedure, TSender> = Class(TList<TProc>)
Procedure Add (Const Value: TProc); Procedure Remove(Const Value: TProc); Procedure Call (Sender: TSender); End; Zitat:
(dieses nimmt der Compiler auch kommentarlos entgegen)
Delphi-Quellcode:
Wie kann ich also dem Compiler sagen, daß dieses "TProc" einen Methoden-Zeiger darstellen soll?
Type TEvent = Procedure(Sender: TMyObject) of Object;
TEventList = TCallback<TEvent, TMyObject>; [add] Wenn sich für den Aufruf nichts finden läßt, dann werde ich wohl doch zumindestens die Call-Prozedur ohne Generics lösen und für jede Methoden-Zeiger eine eigene Klasse von dem Basistypen
Delphi-Quellcode:
ableiten
TInternalCallback<TProc> = Class(TList<TProc>)
|
Re: generische Callback-Liste erstellen ?
Delphi-Quellcode:
Man sollte niemals Typenparameter mit konkreten Typen verwechseln. TProc ist ein in SysUtils definierter Typ.
type
TInternalCallback<T> = class(TList<T>) procedure Add(const Value: T); virtual; abstract; procedure Remove(const Value: T); virtual; abstract; end; TCallback<T> = class(TInternalCallback<TProc<T>>) procedure Call(const Sender: T); end; procedure TCallback<T>.Call(const Sender: T); var i: Integer; begin for i := 0 to Count - 1 do Items[i](Sender); end; Alternativ:
Delphi-Quellcode:
type
TEvent = procedure of object; TEvent<T> = procedure(Sender: T) of object; TInternalCallback<T> = class(TList<T>) procedure Add(const Value: T); virtual; abstract; procedure Remove(const Value: T); virtual; abstract; end; TCallback<T> = class(TInternalCallback<TEvent<T>>) procedure Call(const Sender: T); end; procedure TCallback<T>.Call(const Sender: T); var i: Integer; begin for i := 0 to Count - 1 do Items[i](Sender); end; |
Re: generische Callback-Liste erstellen ?
Das mit dem TProc ist eigentlich kein Problem, da hier das TProc aus der SysUtils lokal mit meinem TProc überschrieben wird,
aber ich nehm mich deinem Vorschlag an und werde es ohne die T's schreiben.
Delphi-Quellcode:
Aber die Idee das TEvent nochmals vorzudeklarieren war eine gute Idee, denn so weiß der Compiler jetzt, daß es ein Methodenzeiger ist. :thumb:
type TCallback<Proc, Sender> = class..
Hatte das Event ja erst nachher deklariert. Werde das TEvent aber noch mit in den Public-Bereicht des TCallback verschieben. :angel2: (ich denke mal, daß sollte auch funktionieren) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:54 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