Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Listen zurückgeben - best practice (https://www.delphipraxis.net/149878-listen-zurueckgeben-best-practice.html)

Meflin 1. Apr 2010 13:48


Listen zurückgeben - best practice
 
Ich habe Funktionen, die prinzipiell generische Listen erstellen, mit denen weitergearbeitet können werden soll.

Intuitiv würde man schreiben:
Delphi-Quellcode:
function foo(): TList<MyClass>
Daraus ergibt sich natürlich das altbekannte Problem: wer gibt diese Liste wann wieder frei? Ist dies nun vertretbar, das dem Benutzer der Library zu überlassen?

Oder sollte man doch besser nen Iterator/Enumerator (was ist eigentlich der Unterschied?) zurückgeben, aber wie würde das konkret funktionieren, im Hinblick auf die generische Liste?

Delphi-Quellcode:
function foo(): ?
var
  List: TList<MyClass>;
begin
  List := TList<MyClass>.Create;
  ...
  Result := ?
end;
Selbst wenn man den Fragezeichenteil korrekt ergänzen könnte :mrgreen: hätte man aber doch immernoch das selbe "Speicherleck"?! Mir fehlt grade die zündende Idee...

himitsu 1. Apr 2010 13:53

Re: Listen zurückgeben - best practice
 
Delphi-Quellcode:
procedure foo(result: TList);
begin
  ...
end;


List := TList<MyClass>.Create;
foo(List);
List.Free;

Neutral General 1. Apr 2010 13:54

Re: Listen zurückgeben - best practice
 
Also ich habe es bisher über einen var/out Parameter gelöst.

Da kann der Benutzer der Funktion nicht aus Versehen den Rückgabewert ignorieren.
Also sowas wie:

Delphi-Quellcode:
function foo(): TList<MyClass>
begin
  Result := ...
end;


begin
  foo(); // BÖSE
end;
geht dann nicht.

Bei mir ginge es dann so:

Delphi-Quellcode:
function foo(var Result: TList<MyClass>): Irgendwas; // oder Procedure
begin
  Result.DoSomething;
  Result.Add(Irgendwas);
end;

var AList: TList<MyClass>;
begin
  AList := TList<MyClass>.Create(...);
  try
     foo(AList);
     // Do something with AList
  finally
    AList.Free;
  end;
end;

Meflin 1. Apr 2010 13:56

Re: Listen zurückgeben - best practice
 
out-Parameter möchte ich nach Möglichkeit vermeiden...

s.h.a.r.k 1. Apr 2010 13:57

Re: Listen zurückgeben - best practice
 
Delphi-Quellcode:
function CreateFoo(): TList<MyClass>;
begin
  ...
end;

List := CreateFoo();
List.Free;
Die Lösung von himitsu wird wohl die beste sein, da man den Code dann einfacher lesen kann. Um aber ab und zu ein wenig Code einzusparen, nutze ich aber gerne obige Konstruktion. Ich setze vor den Methodennamen noch ein "Create", sodass ich dann beim Aufruf sehe, dass etwas erzeugt wird. Ein wirklicher Vorteil ists nicht.

p80286 1. Apr 2010 16:42

Re: Listen zurückgeben - best practice
 
Darf ich mich hier einklinken?
was ist z.B. mit solchen Konstrukten:
Delphi-Quellcode:
function Testlesen(fn:string):tstringlist;
var
  tl : tstringlist;
begin
  tl:=tstringlist.create;
  tl.loadfromfile(fn);
  tl.sort;
  result:=tl;
end;

...
form1.memo1.text:=Testlesen('c:\meinedatenwoauchimmer').text;
....
Da sollte die Stringliste ja auch bis zum Programmende Speicher belegen.

Gruß
K-H

DeddyH 1. Apr 2010 16:44

Re: Listen zurückgeben - best practice
 
Jepp, das kann man mit FastMM schön überprüfen.

Meflin 1. Apr 2010 16:51

Re: Listen zurückgeben - best practice
 
Weils irgendwie grade passt :mrgreen:

Was ist eigentlich damit:
Delphi-Quellcode:
foo = record
  bar: TList<wuppdi>;
end;

...

function k(): foo;
a := k();
Gibts ein Speicherleck oder wird die Liste mit aufgeräumt?


Garbage Collection FTW.

Neutral General 1. Apr 2010 17:00

Re: Listen zurückgeben - best practice
 
Das gibt ein Speicherleck, wenn du die Liste im Record erstellst, aber nicht freigibst.

Zitat:

Garbage Collection FTW.
Ich vertraue den Viechern nicht^^ Als ich mal was mit C# gemacht hab, hat mir das GAR NICHT gepasst, dass der GC meinen Müll erst keine-Ahnung-wann aufgesammelt hat :mrgreen: Ich passe da lieber selbst auf :stupid:

s.h.a.r.k 1. Apr 2010 17:01

Re: Listen zurückgeben - best practice
 
Außer man setz einen Destructor zusätzlich ein, man muss diesen dann aber halt auch aufrufen :zwinker:


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:41 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