Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Record, Array, Class und Schreiben in das Array (https://www.delphipraxis.net/215468-record-array-class-und-schreiben-das-array.html)

matashen 9. Jul 2024 14:26

Delphi-Version: 5

Record, Array, Class und Schreiben in das Array
 
Hallo zusammen,

ich steh voll auf den Schlauch und bin mir sicher für einige hier ist das was ich brauche pillepalle. Der Titel ist auch doof aber was besseres fällt mir auch hier nicht ein... und Kaffee ist heute aus :(

Ich hab ein Record der verkürzt so aussieht

Delphi-Quellcode:
type TProgReleaseItem=record
        ProductID:Integer;
        MachineTypeName:String;
        ProgfieldName:String;
end;
eine Klasse dazu wo dieser Record als array deklariert ist
Delphi-Quellcode:
type TProgRelease=class(TObject)
     strict private
       FItem: TArray<TProgReleaseItem>;
       function getItem(Index:Integer):TProgReleaseItem;
...
       property Item[Index:Integer]:TProgreleaseItem Read GetItem;
wie muss ich den setter schreiben das ich sowas machen kann wie

Delphi-Quellcode:
meinRelease.Item[x].ProductID:='Testeintrag';
Schonmal vielen Dank an euch

Gruß Matthias

himitsu 9. Jul 2024 14:39

AW: Record, Array, Class und Schreiben indas Array
 
Garnicht.

Es wird beim Zugriff auf einen Property leider immer nur entweder der Getter oder der Setter benutzt.

Da hier auf eine Eigenschaft des Records zugegriffen wird, wird also der Getter benutzt und der Schreibzugriff auf das Record-Feld geht dann in die Kopie des Records (also ins Result des Getter)
und wird anschließend nicht automaisch via Setter zurückgeschrieben. (abgesehn davon, dass du eh keinen Setter hast)

* eine Datenklasse anstatt des Records (kann auch eine zuzätliche Access-Implementation sein, welche ihre Proertyzugriffe auf den Record umleitet)

* das Property als Pointer
Delphi-Quellcode:
property Item[Index:Integer]: PProgreleaseItem Read GetItem;


* den Record mit Property+Setter, wobei der Record vom GetItem einen Zeiger auf TProgRelease mitbekommt, um Änderungen weiterzugeben.

* ...

jaenicke 9. Jul 2024 14:41

AW: Record, Array, Class und Schreiben indas Array
 
Mit einem Record geht das nicht, es sei denn du verwendest Pointer. Grund: Beim Zugriff auf den Getter bekommst du eine Kopie des Records. Wenn du nun also etwas in den Record schreibst, passiert das in der Kopie, nicht im Original in der Liste.

Das ist mit einer Klasse viel einfacher, denn das ist von Hause aus nur eine Referenz, so dass es sofort funktioniert. Wenn dir die Referenzzählung wichtig ist, der Speicher also automatisch freigegeben werden soll, kannst du auch ein Interface mit der Klasse verwenden.

matashen 10. Jul 2024 05:10

AW: Record, Array, Class und Schreiben indas Array
 
Also das der Setter fehlt hab ich im Text geschrieben, Zitat: wie muss ich den setter schreiben das ich sowas machen kann wie ...

Wenn das geht als Klasse und ich den Record entsprechend umschreiben muss, kein Problem. Ein kleines Beispiel wär nicht schlecht da ich heute immer noch aufm Schlauch stehe.

Das bei einem Record nur eine Kopie gezogen wird war mir nicht klar. Dachte das auch dort nur intern ein Pointer gesetzt wird. Danke für dir Info.

jaenicke 10. Jul 2024 08:00

AW: Record, Array, Class und Schreiben in das Array
 
Im einfachsten Fall schreibst du statt record einfach Klasse und du bist was den Zugriff inkl. Schreiben angeht fertig. ;-)
Die einzige andere Änderung ist, dass du die Instanzen dann explizit mit Create erstellen musst, sprich
Delphi-Quellcode:
FItems[0] := TProgReleaseItem.Create;
, aber ich frage mich, ob du das überhaupt so möchtest. Mit dem Array ist das unnötig kompliziert.

Viel einfacher:
Delphi-Quellcode:
uses
  System.Generics.Collections;

type
  TProgReleaseItem = class
  public
    ProductID: Integer;
    MachineTypeName: String;
    ProgfieldName: String;
    constructor Create(AProductID: Integer; AMachineTypeName: String; AProgfieldName: String);
  end;

  TProgRelease = class(TObjectList<TProgReleaseItem>)
  end;

constructor TProgReleaseItem.Create(AProductID: Integer; AMachineTypeName: String; AProgfieldName: String);
begin
  ProductID := AProductID;
  MachineTypeName := AMachineTypeName;
  ProgfieldName := AProgfieldName;
end;

var
  Test: TProgRelease;
begin
  Test := TProgRelease.Create(True);
  try
    Test.Add(TProgReleaseItem.Create(1, '2', '3'));
    DoSomething(Test);
  finally
    Test.Free;
  end;
end;
Natürlich wären ggf. propertys statt einfacher Felder sinnvoller, aber funktionieren tut es so.

matashen 10. Jul 2024 08:42

AW: Record, Array, Class und Schreiben in das Array
 
Hi jaenicke,


generische Listen, danke für den Tip.

hatte ich nicht aufn Schirm.

Ich bau dann mal das um.

Wenn ich in einem ListenItem die einzelnen Records zu propertys ändere noch was beachten, oder reichts wenn ich die Variablen wie üblich ins private schreibe und den getter und setter einfach darauf lege?


Gruß Matthias

PS:
Wärst du nicht so elendig weit weg würd ich dich jetzt aufn Mittagsessen einladen.

himitsu 10. Jul 2024 08:46

AW: Record, Array, Class und Schreiben in das Array
 
Und wenn das gespeichert werden soll, statt Liste vielleicht eine Collection ... geht auch generisch.

matashen 10. Jul 2024 09:15

AW: Record, Array, Class und Schreiben in das Array
 
OK Collection Generisch kenn ich noch nicht - wie funktioniert das? Dachte die Generische Listen vom Beispiel jaenicke wäre eine Collection

himitsu 10. Jul 2024 09:39

AW: Record, Array, Class und Schreiben in das Array
 
Collections sind auch Listen, also prinzipiell.

Bei der TCollection ist es aber grundsätzlich so, dass immer nur ein Typ in der "Liste" steckt.
Bei den TList, und vor allem bei der generischen TList<>, können auch Nachfahren der Item-Klasse drin stecken.

Die Collection und ihre Items sind auch so gestaltet, dass sie automatisch serialisiert wird. (also selbst oder z.B. im DFM-Reader/Writer)
Und beim Ändern der Größe der Liste wird die Item-Instanz ebenfalls automatisch verwaltet.

Also erstmal wie OwnsObjects bei der TObjectList bzw. TList<>, wird es freigegeben, aber auch beim Hinzufügen, wird die Item-Instanz automatisch erstellt.
Und es gibt einen Default-PropertyEditor für den FormDesigner, um dort Collections zu bearbeiten. (die Items vieler VCL-Komponenten, wie z.B. Actions, ButtonsGroups, Gestures, Grids, Skia, Taskbars uvm.)

Für die VCL, wenn ausschließlich über den FormDesigner bearbeitet, da ist das generische nicht.
Soll die Liste/Collection vom Code aus bearbeitet werden, dann ist eine manuelle Ableitung oder eine Generische, halt sehr hilfreich, da grundsätzlich keine Casts nötig sind und immer der entsprechende Item-Typ aus den Property und Methoden der Liste kommt.

matashen 11. Jul 2024 09:51

AW: Record, Array, Class und Schreiben in das Array
 
Guten Morgen DP,

hab jetzt den Code umgeschrieben von Record auf Class, leider kommen die Daten in der Liste nicht an, abweichend zu jaenicke habe ich nicht beim Item.Create die ganzen Variablen übergeben sondern ein Item erstellt, befüllt und dann per Add hinzugefügt. Es wird auch ein Item erstellt zumindest geht der Count hoch, aber der Inhalt ist dann leer. Muss ich wirjklich im Create des Items die Variablen schreiben, dachte das geht automatisch. Hab auch gegoogelt und dieses Beispiel sieht ziemlich nach meiner Anwendungaus.
https://www.codersblog.de/generische-listen-in-delphi/

Code Teile zusammenkopiert

Delphi-Quellcode:
type TProgReleaseItemClass=Class
      public
        ProductID:Integer;
        MachineTypeName:String;
        ProgfieldName:String;
     
End;
erweitert um einen Index - brauch ich für spätere Funktionen
Delphi-Quellcode:
type TProgReleaseclass=class(TObjectlist<TProgreleaseItemClass>)
       private
          FSelectedItem:Integer;
       public
       property ItemIndex:Integer read FSelectedItem write FSelectedItem;

end;

var  ReleaseSteps:TProgreleaseClass;
      myitem:TProgreleaseitemClass;

...
Releasesteps:=TProgreleaseClass.Create(true);
...
myitem:=TProgreleaseitemClass.create;
myitem.ProductID:=1234;
myitem.MachineTypeName:='Wunschkiste';
myitem.ProgfieldName:='Test';

releasesteps.add(myitem);
myitem.Free;
und dann versuche ich Daten raus zu lesen, bekomm aber nichts da ich

Gruß Matthias


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:47 Uhr.
Seite 1 von 2  1 2      

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