Funktionen mit Objekten als Rückgabewert

    Funktionen mit Objekten als Rückgabewert

    Hallo,

    ich bin mir gerade uneins: In mehreren Anwendungen erzeuge ich am laufenden Band Objekte, die dann in einer TList<> verwaltet werden.
    Soweit so gut.
    Jetzt will ich mir die Arbeit noch mehr vereinfachen und schon das temporäre Objekt (welches dann in der TList landet) in einer
    Funktion erzeugen und mit Eigenschaften versehen.
    Beispiel: Ich brauche eine Liste von TPanel

    Delphi-Code

    1. for nummer:=von to bis do
    2. begin
    3. tmp:=TPanel.create(Self);
    4. tmp.Name:='X'+nummer.tostring;
    5. tmp.caption:= adresse[nummer];
    6. tmp.font.Size:= 12; // u.s.w.
    7. myList.Add(tmp);
    8. end;


    Die Versorgung mit den spezifischen Werten könnte ich doch samt Erzeugung in eine Funktion ausklammern:

    Delphi-Code

    1. function Versorgen( Owner : TObject; adressen:TAdrssen; nummer:integer; fsize:integer; ...):TPanel;
    2. var tmp:TPanel;
    3. begin
    4. tmp:=TPanel.create(Owner); // (1)
    5. // jetzt tmp wie oben mit Eigenschaften versorgen
    6. Result:= tmp; // (2)
    7. end;

    und dann..

    Delphi-Code

    1. Pani:= Versorgen(Self, Adressliste, 0,12,...);


    Ist diese Vorgehensweise korrekt ? Da bin ich mir eben nicht sicher, da ja der Speicherplatz für das lokale tmp erzeugt (1)
    und nach außen (2) weitergereicht wird.
    Kann Pani dann korrekt freigegeben werden ?
    Oder sollte man Objekte lieber in dem Scope erzeugen, in dem sie benutzt werden und nur noch das "fertige" Objekt mit einer
    Funktion parametriesieren ?
    ism
    Morgen ist Heute schon Gestern
    Warum verwendest Du überhaupt ein temporäres Objekt?

    Delphi-Code

    1. function Versorgen(Owner: TObject; Adressen: TAdressen; Nummer: Integer; Size: Integer; ...): TPanel;
    2. begin
    3. Result := TPanel.Create(Owner);
    4. // jetzt Result mit Eigenschaften versorgen
    5. // ...
    6. end;

    Nur so am Rande:
    Ich war mal so frei und habe Deinen Beispielcode mal ein bisschen lesbarer geschrieben :D
    Warum sollte Beispielcode nicht so sauber formatiert werden wie Produktivcode?
    "Versorgen" finde ich in dem Zusammenhang auch einen denkbar schlechten Namen für eine Methode.
    Bist Du sicher, dass Du in x Monaten anhand des Namens noch weißt was die macht bzw. machen soll?
    "After three days without programming, life becomes meaningless." (The Tao of Programming, Book 2)
    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand" (Martin Fowler, 'Refactoring')
    Hallöle... 8o

    Prinzipiell spricht nichts dagegen das Objekt in einer function zu Erzeugen und zu füllen.... Du solltest die function aber so benennen daß kein Zweifel besteht das eine Instanz erzeugt wird. 8o
    Beispiel:

    Delphi-Code

    1. function CreatePanelBlubb(Bla: string): TPanel


    Beispiel für Erzeugen eines Objektes:

    Delphi-Code

    1. BlubbItem := Listview.Items.Add

    ...hier kümmert sich die Listview um das Freigeben der Items. In deinem Falle mußt du das selbst machen... oder eine Objektliste etc. 8o

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „haentschman“ ()

    Ah ja,

    sehr aufschlußreich.
    @BerndG: Wo war nun die Antwort auf meine Fragen ?
    Und warum sollte ich nicht ein temporäres Objekt nehmen ?
    Macht sich bei größeren Sachen manchmal ganz praktisch zum Debuggen.
    Und zur Formatierung: Der Editor hier ist eine ziemliche Krücke.

    @haentschman: Danke, man darfs also.

    BlubbItem := Listview.Items.Add;

    Coole Namensgebung , aber als Beispiel gehts... 8o
    Keider funktioniert diese Syntax mit TList<> nicht (eben probiert).

    ism
    Morgen ist Heute schon Gestern
    Hallöle... 8o
    Und warum sollte ich nicht ein temporäres Objekt nehmen ?

    Du kannst das Objekt nach dem Create direkt dem Result zuweisen. Auch ein Result kann man debuggen. :thumbsup: Auch wenn du noch Eigenschaften des Objektes manipulierst... Keine Verschwendung von wertvollen Bits und Bytes.... :thumbsup:
    Keider funktioniert diese Syntax mit TList<> nicht (eben probiert).

    8| verstehe ich nicht... Da ist ein Beipiel für eine Rückgabe eines ListView Items. Was hast du denn vor?
    TList<>

    ...ist nicht die gute Wahl. Die räumt nicht die Objekte weg die du selbst erzeugst. Besser TObjectList<>... docwiki.embarcadero.com/Librar…s.Collections.TObjectList

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „haentschman“ ()

    Man kann sich ja auch eine Klasse selbst schreiben, die die angesprochene Funktionalität bereitstellt. Minimalbeispiel:

    Delphi-Code

    1. unit TestList;
    2. interface
    3. uses System.Generics.Collections, VCL.Controls, VCL.ExtCtrls;
    4. type
    5. TPanelList = class
    6. strict private
    7. FInternalList: TObjectList<TPanel>;
    8. function GetItemCount: integer;
    9. function GetItems(Index: integer): TPanel;
    10. public
    11. constructor Create;
    12. destructor Destroy; override;
    13. function Add(AParent: TWinControl = nil): TPanel;
    14. property ItemCount: integer read GetItemCount;
    15. property Items[Index: integer]: TPanel read GetItems; default;
    16. end;
    17. implementation
    18. { TPanelList }
    19. function TPanelList.Add(AParent: TWinControl): TPanel;
    20. begin
    21. Result := TPanel.Create(nil);
    22. Result.Parent := AParent;
    23. FInternalList.Add(Result);
    24. end;
    25. constructor TPanelList.Create;
    26. begin
    27. FInternalList := TObjectList<TPanel>.Create;
    28. end;
    29. destructor TPanelList.Destroy;
    30. begin
    31. FInternalList.Free;
    32. inherited;
    33. end;
    34. function TPanelList.GetItemCount: integer;
    35. begin
    36. Result := FInternalList.Count;
    37. end;
    38. function TPanelList.GetItems(Index: integer): TPanel;
    39. begin
    40. Result := FInternalList.Items[Index];
    41. end;
    42. end.
    10 Minuten Nachdenken ersparen oftmals 10 Stunden Fehlersuche.