![]() |
Delphi-Version: 10 Seattle
Fragen zu Generic TList
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
ich habe mich etwas mit Generic TList beschäftigt und hänge nun bei ein paar Punkten. Hier zunächst Code-Auszüge (im Anhang das ganze Projekt).
Delphi-Quellcode:
Folgende Fragen:
TMyClass = class
private FCounter, FValue: Integer; public property Counter: Integer read FCounter write FCounter; property Value: Integer read FValue write FValue; end; TMyList = class(TList<TMyClass>) private FFreeOnDelete: Boolean; procedure Notify(Ptr: Pointer; Action: TListNotification); virtual; public constructor Create(bValue: Boolean = true); end; var MyList: TMyList; MyCopyList: TMyList; MyList := TMyList.Create; MyCopyList := TMyList.Create(false); // In Copyliste bei Delete Daten nicht löschen // Datenliste erzeugen for i := 0 to 50 do begin Values := TMyClass.Create; Values.Counter := i; Values.Value := random(200); MyList.Add(Values); end; // Datenliste in Memofeld anzeigen for i := 0 to MyList.Count - 1 do begin Values := MyList.Items[i]; Memo1.Lines.Add(format('%d: %d, %d', [i, Values.Counter, Values.Value])); end; // Datenliste kopieren for i := 0 to MyList.Count - 1 do begin Values := MyList.Items[i]; MyCopyList.Add(Values); end; // Jeden 10 Datensatz in kopierter Liste löschen MyCopyList.Delete(40); MyCopyList.Delete(30); MyCopyList.Delete(20); MyCopyList.Delete(10); // gelöscht werden aber die letzten 4 Datensätze procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin MyCopyList.Free; MyList.Free; end; { TMyList } constructor TMyList.Create(bValue: Boolean = true); begin inherited Create; FFreeOnDelete := bValue; end; procedure TMyList.Notify(Ptr: Pointer; Action: TListNotification); begin if (FFreeOnDelete) and (Action = lnDeleted) then TObject(Ptr).Free; // inherited Notify(Ptr, Action); end;
Danke für eure Unterstützung Gerd |
AW: Fragen zu Generic TList
Hat es einen bestimmten Grund, dass du nicht TObjectList<TMyClass> verwendest?
|
AW: Fragen zu Generic TList
Deine Funktion wird korrekt ausgeführt, aber deine Ausgabefunktion hat einen Fehler:
Delphi-Quellcode:
Du zeigst die Einträge der originalen Liste an, benutzt aber die Anzahl der kopierten Liste als Maximum.
Memo2.Clear;
for i := 0 to MyCopyList.Count - 1 do begin Values := MyList.Items[i]; Memo2.Lines.Add(format('%d: %d, %d', [i, Values.Counter, Values.Value])); end; |
AW: Fragen zu Generic TList
Moin...:P
Du macht es dir schwerer als es in Wirklichkeit ist. :zwinker: Bei deinen 2 Listen gibt es einiges zu beachten. 1. Eine Masterlist die die Werte hällt und die Werte freigibt. (TObjectList) 2. Die Liste mit den kopierten Werten hällt. (TList) Diese Liste hällt nur die Pointer der Values aus der Masterliste. 3. Die Einträge können direkt mit TList.Delete aus der Liste entfernt werden. Das Original bleibt davon unberührt.
Delphi-Quellcode:
...wie ich auch in dem anderen Thread sagte, du solltest die TObjectList benutzen.
for i := 0 to 50 do
begin Values := TMyClass.Create; // ein Pointer wird erzeugt Values.Counter := i; Values.Value := random(200); MyList.Add(Values); // ein Pointer liegt in der Liste und wird mit TList [B]nicht[/B] freigegeben end;
Delphi-Quellcode:
...das Legen in die MyCopyList legt nur den Pointer der Instanz aus der MasterList in die MyCopyList.
for i := 0 to MyList.Count - 1 do
begin Values := MyList.Items[i]; MyCopyList.Add(Values); end;
Delphi-Quellcode:
... die Freigabe der Values braucht hier nicht erfolgen. Das erledigt die MasterList über OwnsObjects.
TMyList = class(TList<TMyClass>)
private FFreeOnDelete: Boolean; // nicht notwendig da die Pointer in dieser Liste nicht freigegeben werden müssen procedure Notify(Ptr: Pointer; Action: TListNotification); virtual; // nicht notwendig da die Pointer in dieser Liste nicht freigegeben werden müssen public constructor Create(bValue: Boolean = true); end; :wink: |
AW: Fragen zu Generic TList
Die Kopie-Liste kann doch auch eine TObjectList sein, nur eben mit OwnsObjects auf false, oder mache ich gerade einen Denkfehler?
|
AW: Fragen zu Generic TList
Zitat:
|
AW: Fragen zu Generic TList
Das mit den TObjectList hatte ich schon verstanden und will es mir auch noch anschauen. Zuerst wollte ich aber mal die TList verstehen da eine für mich wichtige Anwendung mit TList<> arbeitet und ich noch nicht abschätzen kann welche Auswirkungen ein Wechsel auf TObjectList hat. :(
Zweifel an meinem Verständnis hatte ich aufgrund der vermeintlich falsch gelöschten Daten in der Kopierliste. Deshalb Dank an Ensaron's Hinweis, dass es sich um einen typischen Paste&Copy Fehler handelt.:-D Jetzt würde ichnur noch gerne verstehen, wie ich das Notify korrekt implementiere. Danach stürze ich mich auf TObjectList. Versprochen.:thumb: |
AW: Fragen zu Generic TList
Zitat:
|
AW: Fragen zu Generic TList
Zitat:
Du erzeugst eine neue Notify Procedure mach es so:
Delphi-Quellcode:
TMyList = class(TList<TMyClass>)
private FFreeOnDelete: Boolean; // Die Notify ist protected protected procedure Notify(const Ptr: tMyclass; Action: TCollectionNotification); override; // Überschreiben nicht virtual public constructor Create(bValue: Boolean = true); end; |
AW: Fragen zu Generic TList
Die Warnmedlung hatte ich gesehen, nur wusste ich nichts damit anzufangen. Auch nachdem ich noch mal in Netz gesucht habe. Gut dass du mich direkt darauf gelüpft hast.
Viel weiter gekommen bin ich aber noch nicht, denn jetzt bin ich wieder bei Zitat:
Delphi-Quellcode:
ändere mag er den Typ T nicht.
procedure Notify(const Item: T; Action: TCollectionNotification); override;
|
AW: Fragen zu Generic TList
Ich hatte die Signatur noch mal geändert, (war nur so aus dem Kopf),
mit der aktuellen Signatur sollte es gehen siehe oben |
AW: Fragen zu Generic TList
Noch mal 1mm weiter aber immer noch nicht am Ziel.
Jetzt streikt der Aufruf
Delphi-Quellcode:
Beim Aufruf von Ptr.Free kommt es zu einer Exception "Ungültige Zeigeroperation". Dispose(Ptr) ging auch nicht.
procedure TMyList.Notify(const Ptr: TMyclass; Action: TCollectionNotification); // Überschreiben nicht virtual
begin if (FFreeOnDelete) and (Ptr<>nil) and (Action = cnRemoved) then Ptr.Free; // Ungültige Zeigeroperation inherited Notify(Ptr, Action); end; Ausserdem: Ich bin dr Meinung, dass inherited nach meiner Aktion erfolgen soll aber auf der Suche fan ich auch Beispiele, wo zuerst inherited aufgerufen wurde. Spielt es eine Rolle? |
AW: Fragen zu Generic TList
.. nur mal ein Schuss ins Blaue - an dem const Parameter kann es nicht liegen?
oder Ptr ist bereits woanders freigegeben und nicht auf nil gesetzt worden . Grüße Klaus |
AW: Fragen zu Generic TList
Hallöle...8-)
Delphi-Quellcode:
..du gibst immer noch den Pointer frei der in der Gesamtliste beibehalten werden soll. Die Liste muß dich über nix in informieren... (Notify kann weg) :roll: Einfach den Listen Eintrag mit DELETE entfernen...fertsch. 8-) Die Instanzen der Hauptliste werden mit der TObjectList, wenn du endlich mal eine hast, weggeräumt. 8-)
procedure TMyList.Notify(const Ptr: TMyclass; Action: TCollectionNotification); // Überschreiben nicht virtual
begin if (FFreeOnDelete) and (Ptr<>nil) and (Action = cnRemoved) then Ptr.Free; // Ungültige Zeigeroperation inherited Notify(Ptr, Action); end; Zitat:
|
AW: Fragen zu Generic TList
Zitat:
Zitat:
Zitat:
![]() |
AW: Fragen zu Generic TList
Liste der Anhänge anzeigen (Anzahl: 1)
Hallöle...:P
Zitat:
Zitat:
Zitat:
Hinweis: Zitat:
|
AW: Fragen zu Generic TList
Hallo,
Zitat:
Weil ich es eben so verstanden hatte, dass TObjectList nur das zusätzlich Löschen hat, habe ich nicht verstanden warum dann in dem andern Thread zu TList geraten wird. In meinem Projekt habe ich schon auf TObjektList umgestellt. Dein Leckanzeiger werde ich gleich mal ausprobieren:thumb: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:26 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