![]() |
class property : array of Record (Felder ansprechen)
Hallo,
angeregt durch einen andere Thread versuche ich mich gerade an Array-Propertys. Mit Array of Standard-Type funktioniert das. Auch mit Array of MyRecord, aber dort würde ich gerne gleich auf die Record-Felder zugreifen. Leider hört es bei mir auf, wenn es sich Standard-Deklarationen in Klassen entfernt.
Delphi-Quellcode:
Wie muss ich das angehen, um direkt auf das Feld innerhalb des deklarierten Record's zugreifen zu können?
type
TMyRecord = record name : String; value : Integer; end; TMyArray = array of TMyRecord; LittleTestList = class(TObject) private FItems : TMyArray; function GetItem(index: Integer): TMyRecord; procedure SetItem(index: Integer; const Value: TMyRecord); public property Items[index: Integer]: TMyRecord read GetItem write SetItem; default; end; [...] procedure TForm1.Button1Click(Sender: TObject); var aRecord : TMyRecord; begin LittleTestList.Items[1] := aRecord; // OK LittleTestList[1] := aRecord; // OK LittleTestList.Items[1].name := aRecord.name; // Linken Seite kann nichts zugewiesen werden end; |
Re: class property : array of Record (Felder ansprechen)
Denk mal nach. Wie sollte Delphi das umsetzen? Weder durch GetItem noch durch SetItem kann dieses Verhalten implementiert werden. Du kannst das Problem umgehen, indem du entweder Zeiger oder Klassen verwendest.
|
Re: class property : array of Record (Felder ansprechen)
Danke für die schnelle Antwort.
Sah zumindest vielversprechend aus, da er die Record-Felder in der Auto-Vervollständigung angeboten hatte. Gut dann löse ich die Felder in einzelne propertys auf... dachte ich könnte hier eine Vereinfachung erzwingen. Wenn es zuviel wird, wird wohl eine Klasse für MyRecord interessant werden. Damit experimentiere ich gleich mal... |
Re: class property : array of Record (Felder ansprechen)
du erstellst doch in GetItem eine Kopie des Records
und diese Kopie ist dann in Result (einer delhpiinternen Variable) enthalten. und selbst wenn du hier Links was zuweisen könntest, dann würde nur die Kopie geändert, aber nicht das Original. |
Re: class property : array of Record (Felder ansprechen)
Hallo Zusammen,
ich denke das Problem liegt in SetItem. Da hier nur ein vollständiger Record übergeben wird müßte sozusagen ein zwischenschritt eingebaut werden: Setitemfeld(i,feld) rec:=Getitem(i); rec.Feld:=feld; setitem(i,rec) so ungefähr. rec wäre dann eine (zu setitemfeld) lokale variable in die man problemlos feldinhalte einbringen kann. Danach wird dann (wie üblich) ein vollständiger Record wieder weggeschrieben. Ist nicht getestet und wahrscheinlich nicht oop, aber vielleicht eine Idee. Gruß K-H |
Re: class property : array of Record (Felder ansprechen)
Ja GetItem ist nicht das Problem
Delphi-Quellcode:
das funktioniert.
aRecord.name := LittleTestList.Items[1].name;
Aber sehe schon was da falsch läuft... (Dank p80286s Ausführung) Bei SetItem wird der Record übergeben. Wenn ich nur ein Feld zuweise, dann könnte Delphi SetItem nur einen unvollständigen Record übergeben. SetItem wüsste auch nie, welches Feld jetzt einen gültigen Wert enthält. PS: Im Speicher liegt noch ein kompletter 80286 mit Hercules Grafikkarte und MFM Festplatte PS: Werde es ähnlich wie bei einer StringList lösen. procedure Add(Name:String, Int:Integer) und Insert(Index:Integer, Name:String, Int:Integer) zum Schreiben. Da Lesen funktioniert, kann ich mir so eine lokale Variable vom Typ TMyRecord sparen. |
Re: class property : array of Record (Felder ansprechen)
das Problem ist hier
Delphi-Quellcode:
Delphi macht daraus
LittleTestList.Items[1].Name := xyz;
Delphi-Quellcode:
für eine Zuweisung müßte es aber dieses machen
LittleTestList.GetItem(1).Name
Delphi-Quellcode:
und das macht es halt nicht ... wenn sowas man in Delphi eingebaut würde, dann könnte man Properties auch als "Var"-Parameter nutzen
TMyRecord(Temp) := LittleTestList.GetItem(1);
Temp.Name := xyz; LittleTestList.SetItem(1, Temp);
Delphi-Quellcode:
MyFunction({var} LittleTestList.Items[1]);
// müßte zu dem werden TMyRecord(Temp) := LittleTestList.GetItem(1); MyFunction(Temp); LittleTestList.SetItem(1, Temp); // Delphi kennt aber nur diese Variante TMyRecord(Temp) := LittleTestList.GetItem(1); MyFunction(Temp); // also sozusagen nur MyFunction(LittleTestList.GetItem(1)); |
Re: class property : array of Record (Felder ansprechen)
Hallo,
musst du denn unbedingt eine Property verwenden? der Direktzugriff sollte ja funktionieren:
Delphi-Quellcode:
Dazu musst du natürlich FItems als public definieren.
LittleTestList.FItems[1].name := aRecord.name; // Linken Seite kann nichts zugewiesen werden - DOCH
Ich weiss, dass das kein soo sauberer OO-Stil ist und dass einige Möglichkeiten durch Setter/Getter wegfallen, aber wenns denn funktioniert... Gruss Reinhard |
Re: class property : array of Record (Felder ansprechen)
Der direkte Zugriff (auch als property) funktioniert natürlich.
Nur wollte ich schauen, was mit der Variante array-property... mit der netten Zusatz-Eigenschaft "default"... so alles anzustellen ist. |
Re: class property : array of Record (Felder ansprechen)
Hallo zusammen,
ich hab mir das alles nocheinmal durch den Kopf gehen lassen. Der Vorschlag von Reinhard geht ja auch etwas OOPlischer: .. myrecord : TMyrecord read xxxxx write FMyRecord; ... FMyrecord : TMyrecord; Wobei die eigentliche Variable (FMyrecord) immer noch gekapselt wäre. Da der schreibende Zugriff direkt erfolgt, können die einzelnen Record.Felder auch einzeln adressiert werden. Der lesende Zugriff (xxxxx) kann immer noch über eine Funktion erfolgen. (Borland hat es auch so gemacht, und es funktioniert!) Gruß K-H |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:01 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 by Thomas Breitkreuz