AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Fragen zu Generic TList

Ein Thema von norwegen60 · begonnen am 25. Jan 2017 · letzter Beitrag vom 26. Jan 2017
Antwort Antwort
Seite 1 von 2  1 2      
norwegen60

Registriert seit: 23. Dez 2007
Ort: Schwarzwald
504 Beiträge
 
Delphi 12 Athens
 
#1

Fragen zu Generic TList

  Alt 25. Jan 2017, 21:27
Delphi-Version: 10 Seattle
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:
  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;
Folgende Fragen:
  1. Gibt es grundsätzliche Fehler bei der Behandlung
  2. In der Originalliste funktioniert MyList.Delete(30); einwandfrei, in der kopierten Liste wird mit jedem Aufruf der letzte Satz gelöscht. Warum?
  3. Notify zum löschen des Speicherplatz funktioniert nicht und inherited führt gleich zu Fehler. Irgendwie scheint der Header in XE10 nicht dem in der Hilfe zu entsprechen. Aber wie geht es richtig?

Danke für eure Unterstützung
Gerd
Angehängte Dateien
Dateityp: zip TListClass.zip (52,6 KB, 9x aufgerufen)
  Mit Zitat antworten Zitat
SProske

Registriert seit: 16. Feb 2015
Ort: Halle/S.
116 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#2

AW: Fragen zu Generic TList

  Alt 25. Jan 2017, 21:44
Hat es einen bestimmten Grund, dass du nicht TObjectList<TMyClass> verwendest?
Sebastian
  Mit Zitat antworten Zitat
ensaron

Registriert seit: 29. Aug 2008
Ort: 10369 Berlin
63 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Fragen zu Generic TList

  Alt 26. Jan 2017, 06:37
Deine Funktion wird korrekt ausgeführt, aber deine Ausgabefunktion hat einen Fehler:

Delphi-Quellcode:
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;
Du zeigst die Einträge der originalen Liste an, benutzt aber die Anzahl der kopierten Liste als Maximum.
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman
Online

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.292 Beiträge
 
Delphi 12 Athens
 
#4

AW: Fragen zu Generic TList

  Alt 26. Jan 2017, 07:56
Moin...
Du macht es dir schwerer als es in Wirklichkeit ist. 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:
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;
...wie ich auch in dem anderen Thread sagte, du solltest die TObjectList benutzen.
Delphi-Quellcode:
for i := 0 to MyList.Count - 1 do
  begin
    Values := MyList.Items[i];
    MyCopyList.Add(Values);
  end;
...das Legen in die MyCopyList legt nur den Pointer der Instanz aus der MasterList in die MyCopyList.
Delphi-Quellcode:
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;
... die Freigabe der Values braucht hier nicht erfolgen. Das erledigt die MasterList über OwnsObjects.


Geändert von haentschman (26. Jan 2017 um 09:02 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.540 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Fragen zu Generic TList

  Alt 26. Jan 2017, 08:56
Die Kopie-Liste kann doch auch eine TObjectList sein, nur eben mit OwnsObjects auf false, oder mache ich gerade einen Denkfehler?
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman
Online

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.292 Beiträge
 
Delphi 12 Athens
 
#6

AW: Fragen zu Generic TList

  Alt 26. Jan 2017, 09:00
Zitat:
Die Kopie-Liste kann doch auch eine TObjectList sein, nur eben mit OwnsObjects auf false, oder mache ich gerade einen Denkfehler?
...nö. Es ging auch darum die Unterschiede von TObjectList und TList gegenüberzustellen...
  Mit Zitat antworten Zitat
norwegen60

Registriert seit: 23. Dez 2007
Ort: Schwarzwald
504 Beiträge
 
Delphi 12 Athens
 
#7

AW: Fragen zu Generic TList

  Alt 26. Jan 2017, 09:19
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.

Jetzt würde ichnur noch gerne verstehen, wie ich das Notify korrekt implementiere.

Danach stürze ich mich auf TObjectList. Versprochen.
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.110 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: Fragen zu Generic TList

  Alt 26. Jan 2017, 09:24
Jetzt würde ichnur noch gerne verstehen, wie ich das Notify korrekt implementiere.
Schau mal in die WARNUNG-Meldungen des Compilers. Da steht's eigentlich
  Mit Zitat antworten Zitat
Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
678 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Fragen zu Generic TList

  Alt 26. Jan 2017, 10:04
Zitat:
Schau mal in die WARNUNG-Meldungen des Compilers. Da steht's eigentlich
[dcc32 Warnung] fo_Tlist.pas(56): W1010 Methode 'Notify' verbirgt virtuelle Methode vom Basistyp 'System.Generics.Collections.TList<fo_Tlist.TMyCla ss>'

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;
Fritz Westermann

Geändert von Fritzew (26. Jan 2017 um 10:07 Uhr)
  Mit Zitat antworten Zitat
norwegen60

Registriert seit: 23. Dez 2007
Ort: Schwarzwald
504 Beiträge
 
Delphi 12 Athens
 
#10

AW: Fragen zu Generic TList

  Alt 26. Jan 2017, 10:16
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:
[dcc32 Fehler] fo_Tlist.pas(67): E2037 Deklaration von 'Notify' unterscheidet sich von vorheriger Deklaration
und wenn ich es auf procedure Notify(const Item: T; Action: TCollectionNotification); override; ändere mag er den Typ T nicht.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 13:02 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