![]() |
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:
eine Klasse dazu wo dieser Record als array deklariert ist
type TProgReleaseItem=record
ProductID:Integer; MachineTypeName:String; ProgfieldName:String; end;
Delphi-Quellcode:
wie muss ich den setter schreiben das ich sowas machen kann wie
type TProgRelease=class(TObject)
strict private FItem: TArray<TProgReleaseItem>; function getItem(Index:Integer):TProgReleaseItem; ... property Item[Index:Integer]:TProgreleaseItem Read GetItem;
Delphi-Quellcode:
Schonmal vielen Dank an euch
meinRelease.Item[x].ProductID:='Testeintrag';
Gruß Matthias |
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. * ... |
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. |
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. |
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:
, aber ich frage mich, ob du das überhaupt so möchtest. Mit dem Array ist das unnötig kompliziert.
FItems[0] := TProgReleaseItem.Create;
Viel einfacher:
Delphi-Quellcode:
Natürlich wären ggf. propertys statt einfacher Felder sinnvoller, aber funktionieren tut es so.
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; |
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. |
AW: Record, Array, Class und Schreiben in das Array
Und wenn das gespeichert werden soll, statt Liste vielleicht eine Collection ... geht auch generisch.
|
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
|
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. |
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. ![]() Code Teile zusammenkopiert
Delphi-Quellcode:
erweitert um einen Index - brauch ich für spätere Funktionen
type TProgReleaseItemClass=Class
public ProductID:Integer; MachineTypeName:String; ProgfieldName:String; End;
Delphi-Quellcode:
und dann versuche ich Daten raus zu lesen, bekomm aber nichts da ich
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; Gruß Matthias |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:47 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