Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi class property : array of Record (Felder ansprechen) (https://www.delphipraxis.net/131620-class-property-array-record-felder-ansprechen.html)

Satty67 27. Mär 2009 18:14


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:
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;
Wie muss ich das angehen, um direkt auf das Feld innerhalb des deklarierten Record's zugreifen zu können?

Apollonius 27. Mär 2009 18:16

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.

Satty67 27. Mär 2009 18:27

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...

himitsu 27. Mär 2009 18:31

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.

p80286 27. Mär 2009 18:44

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

Satty67 27. Mär 2009 18:50

Re: class property : array of Record (Felder ansprechen)
 
Ja GetItem ist nicht das Problem
Delphi-Quellcode:
  aRecord.name := LittleTestList.Items[1].name;
das funktioniert.

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.

himitsu 27. Mär 2009 20:18

Re: class property : array of Record (Felder ansprechen)
 
das Problem ist hier
Delphi-Quellcode:
LittleTestList.Items[1].Name := xyz;
Delphi macht daraus
Delphi-Quellcode:
LittleTestList.GetItem(1).Name
für eine Zuweisung müßte es aber dieses machen
Delphi-Quellcode:
TMyRecord(Temp) := LittleTestList.GetItem(1);
Temp.Name := xyz;
LittleTestList.SetItem(1, Temp);
und das macht es halt nicht ... wenn sowas man in Delphi eingebaut würde, dann könnte man Properties auch als "Var"-Parameter nutzen

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));

Reinhard Kern 28. Mär 2009 11:46

Re: class property : array of Record (Felder ansprechen)
 
Hallo,

musst du denn unbedingt eine Property verwenden? der Direktzugriff sollte ja funktionieren:

Delphi-Quellcode:
  LittleTestList.FItems[1].name := aRecord.name; // Linken Seite kann nichts zugewiesen werden - DOCH
Dazu musst du natürlich FItems als public definieren.

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

Satty67 28. Mär 2009 18:38

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.

p80286 30. Mär 2009 09:40

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