![]() |
Re: denkfehler; array-> dynarray
Hm, dann habe ich da ein grundlegendes Verständnisproblem, was die Collection angeht. Weil ich sehe nicht, wie ein Objekt in die Liste kommt bzw. ... warte ... ich sehe irgendwas im Nebel schimmern...kann es aber nicht fassen.
Könntets du mir mal bitte eben erklären, wie die TCollection funktioniert? Interessiert wahrscheinlich auch den Threadersteller. |
Re: denkfehler; array-> dynarray
Ehrlich gesagt bin ich mir nicht sicher, ob ich das erklären kann, aber ich versuche es.
Die Collection ist im Prinzip so ähnlich wie eine ObjectList, d.h. du kannst Objekte darin speichern. Allerdings müssen diese Objekte von TCollectionItem abgeleitet werden und pro Collection geht nur ein Objekttyp. Also in dieser Reihenfolge: 1. Ein Objekt mit den gewünschten Eigenschaften/Methoden von TCollectionItem ableiten. 2. Eine Collection von TCollection ableiten und der Bequemlichkeit halber bereits hier die entsprechenden Typcasts auf den Itemtypen vornehmen. Zusätzlich können hier natürlich auch noch Methoden und Eigenschaften, die die gesamte Collection betreffen programmiert werden (z.B. um bei den Viechern zu bleiben, eine "Mutiere"-Methode, die durch alle Viecher in der Collection iteriert und deren Mutieren Methode aufruft). 3. Die Collection mit Daten füllen (Add, Insert) oder die Daten in der Collection bearbeiten (Delete). Den Punkt 2 könntest du auch weglassen, dann musst du die Typcasts halt beim Aufruf der ursprünglichen Methoden machen. Ich nehme mal die Viecher als Beispiel her und gehe davon aus, dass Collection einfach vom Typ TCollection ist.
Delphi-Quellcode:
Ich schreib auch gleich das Beispiel aus Punkt 2 hin, bevor Fragen kommen. "Mutieren" aller Viecher:
var tempViech: TViech;
tempViech := TViech(Collection.Add); //So sieht übrigens das Create von TCollection intern aus constructor TCollection.Create(ItemClass: TCollectionItemClass); begin FItemClass := ItemClass; FItems := TList.Create; NotifyDesigner(Self, Self, opInsert); end; //und so die Add Methode function TCollection.Add: TCollectionItem; begin Result := FItemClass.Create(Self); Added(Result); end;
Delphi-Quellcode:
procedure TViecher.Mutiere;
var i: Integer; begin for i := 0 to Count - 1 do begin Viech[i].Mutiere; end; end; //Im Hauptprogramm ruft man jetzt nur noch eine Methode auf und Mutiert alle Viecher BlaueViecher.Mutiere; |
Re: denkfehler; array-> dynarray
Das mit der Collection sieht gut aus.
2 Fragen: 1. Ist die Anzahl der möglichen Viecher höher oder niedriger wie bei dem array, was ist der vorteil zum array [außer dass es eleganter ist und besser aussieht] 2. kann ich auch kollektion einer kollektion bilden? also angenommen, ich möchte alle viecher verändern, aber den Forschritt festhalten, in dem ich alle Versionen des Viechs habe? z.b [1] viech[1].haare=1 -> mutiere viech[2].haare=2 -> mutiere viech[3].haare=3 [2] verändere alle viecher [+1] viech[1].haare=2 -> mutiere viech[2].haare=3 -> mutiere viech[3].haare=4 [3] verändere alle viecher [+2] viech[1].haare=4 -> mutiere viech[2].haare=5 -> mutiere viech[3].haare=6 meiner ansicht wäre das mit zweierlei varianten möglich, also einmal die collection als array, oder die collection als collection einer collection. :drunken: |
Re: denkfehler; array-> dynarray
Die Zahl der Viecher dürfe groß sein (Durch den Heap begrenzt)
Du kannst Collections verschachteln. Also in einem CollectionItem wieder eine Collection drin haben. Es reicht ein Collection.SaveToFile(...); Um alles zu speichern (inkl. published Properties und Sub-Collections) Siehe auch ![]() ![]() |
Re: denkfehler; array-> dynarray
wie schreib ich da den type? mit den properties= so vllt?
Delphi-Quellcode:
type
TViecher = class(TCollectionitem) protected function GetViech(Index: Integer): TViech; procedure SetViech(Index: Integer; Value: TViech); public function Add: TViech; function Insert(Index: Integer) : TViech; property Viech[Index: Integer]: TViech read GetViech write SetViech; default; end; ... type TViechergruppe = class(TCollection) protected function GetViecher(Index: Integer): TViecher; procedure SetViecher(Index: Integer; Value: TViecher); public function Add: TViecher; function Insert(Index: Integer) : TViecher; property Viecher[Index: Integer]: TViech read GetViecher write SetViecher; default; end; |
Re: denkfehler; array-> dynarray
Jetzt mal was aus dem Tutorial kopiert:
Delphi-Quellcode:
So einfach kann das gehen ;)
TmxCustomItem = class(TCollectionItem)
private fStringItem: String; public procedure Assign(Source: TPersistent); overide; published property StringItem: String read fStringItem write fStringItem; end; (* Dies ist eine normale Itemklasse, doch jetzt kommt der Unterschied zu einer herkömmlichen Collection. Direkt nach der Item-Deklaration schreiben wir folgendes: *) {$define TYPED_DP_COLLECTION_TEMPLATE} _COLLECTION_ITEM_ = TmxCustomItem; {$INCLUDE dpCollection_tmpl.pas} TTypedCollection = _COLLECTION_; |
Re: denkfehler; array-> dynarray
ich hab jetzt noch nich ganz verstanden, was das bring:
Delphi-Quellcode:
{$define TYPED_DP_COLLECTION_TEMPLATE}
_COLLECTION_ITEM_ = TmxCustomItem; {$INCLUDE dpCollection_tmpl.pas} TTypedCollection = _COLLECTION_; |
Re: denkfehler; array-> dynarray
Da Delphi keine Generics unterstütz(te) passiert folgendes:
In der Mitte wird die templae Datei mittels $Include eingebunden. In der Datei wird eine typisierte Collection von dem Typ "_COLLECTION_" erstellt, die genau auf den Typ "_COLLECTION_ITEM_" abgestimmt ist. Dadurch brauchst dcu später nicht mehr casten. Jetzt definiertst du erstmal deine Klasse. Anschließend gibst du ihr den Alias "_COLLECTION_ITEM_" ;) Jetzt wird das Template eingebunden, das zu dieser Klasse eine Collection definiert. Danach erzeugst du wieder einen Alias für die Collection. Ein Alias ist ein anderer Name für den selben Typen. Du kannst also über 2 Namen auf den gleichen Typ zugreifen ;) |
Re: denkfehler; array-> dynarray
Zitat:
Zur zweiten Frage. Das habe ich noch nicht probiert, aber im einfachsten Fall ist es so, dass du einfach im TVich noch eine Collection einbaust. Dabei sieht TViechVersion (TCollectionItem) und TViecherVersion(TCollection) im Prinzip genau so aus, wie TViech und TViecher bisher aussahen. Du kannst da natürlich die Methoden zum Mutieren weglassen, weil du nur Daten darin sichern willst.
Delphi-Quellcode:
nicht vergessen im Constructor:
type
TViech = class(TCollectionItem) private FLaenge: Real; FHaare: Real; FVersion: TViecherVersion; //..weitere Eigenschaften public constructor Create(Collection: TCollection); override; procedure Mutiere; procedure Assign(Source: TPersistent); //..weitere Methoden property Laenge: Real read FLaenge write FLaenge; property Haare: Real read FHaare write FHaare; property Version: TViecherVersion read FVersion write FVersion; //..weitere Eigenschaften end;
Delphi-Quellcode:
und dazu brauchst du dann noch im Destructor:
FVersion := TViecherVersion.Create(TViechVersion);
Delphi-Quellcode:
Die Methode "Mutiere" von TViech könnte dann so aussehen:
FVersion.Free;
Delphi-Quellcode:
procedure TViech.Mutiere;
var tempVersion: TViechVersion; begin tempVersion := Version.Add; tempVersion.Assign(self); //Die aktuelle Version des Viechs zuweisen, bin nicht sicher, ob das so klappt //Eventuell könnte auch dies funktionieren, dann braucht man keine tempVersion -> probieren! Version.Add.Assign(self); //und jetzt wird fröhlich mutiert Laenge := //irgendwas; Haare := //irgendwas; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:30 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