![]() |
Re: Objekt kopieren
Weil man bei Collections soviel tippen muss (eben auch das Assign), hatte ich mir ja
![]() Ein Beispiel, weil ein Assign zu implementieren ist, hat shmia ja in Post #15 stehen (in obigem Link ebenfalls eins). Die "Herausforderung" bei Collections ist da halt immer, daß man, wenn man neue Properties hinzufügt, gerne mal vergisst, auch das Assign zu aktualisieren - dort musst Du halt selber von Hand eine Kopie jeder kopiergewünschten Eigenschaft anlegen (das automatisch machen zu lassen kann imho nicht funktionieren, da es z.B. bei Zeigern auf Objekten je nach Code drumherum darauf ankommen würde, ob man etwa eine TStringList ebenfalls mit Assign auf die neue kopiert, oder nur den Zeiger selber kopiert, wenn er etwa auf ein spezielles externes Objekt zeigt). Warum alzaimar da jetzt eine zusätzliche "Clone"-Methode hat, kann ich mir nur so halb vorstellen, da sie halt auch nicht irgendwie automatisierter laufen kann (imho), und zudem genau dasselbe erledigen soll, was Assign macht - nur daß der Aufruf (Rückgabewert & Parameter) vertauscht ist. |
Re: Objekt kopieren
Zitat:
|
Re: Objekt kopieren
Puh, ich steige da nicht mehr durch. :wall:
Delphi-Quellcode:
So sieht meine Klasse aus. Und davon brauche ich eine Kopie mitsamt der inneren Liste. Was muss ich jetzt konkret wie und wo implementieren, damit man davon eine Kopie erstellen kann?
TPageCollection = Class(TObject);
private FInnerList: TList; x: Double; // ...; // ...; public procedure Add; // ...; // ...; end; procedure TPageCollection.Add(Item: TImageEnVect); begin FinnerList.Add(Item); end; |
Re: Objekt kopieren
Leider kennen die TImages keine eigene Assign-Methode, von daher müsstest Du auch das Kopieren der Eigenschaften Deiner Images von Hand machen. Am Einfachsten wäre es natürlich, wenn Du anstatt einer TList als innerList eine TImagelist verwendest, die kann das nämlich von alleine.
Wenn Du Dir genau ansehen willst, was Du "von Hand" machen musst, um die TList zu kopieren, dann solltest Du Dir das TImagelist.Assign mal ansehen, das könntest Du dann relativ einfach für Deine Liste übernehmen. |
Re: Objekt kopieren
Zitat:
Delphi-Quellcode:
Cu,
Function TMyCollection.Clone : TMyCollection;
Var i : Cardinal; Begin Result := TMyCollection.Create; // <Copy Attributes> For i:=0 to Count- 1 do Result.Add (TMyCollectionItem(Items[i]).Clone); End; Udontknow |
Re: Objekt kopieren
Liste der Anhänge anzeigen (Anzahl: 1)
@Udontknow: Meine Item-Klasse ist vom Typ TList:
Delphi-Quellcode:
oder meinst du den Typ der Objekte in der Liste? Die sind vom Typ TImageEnvect (so was wie ein TImage) und kennt die Methode Assign (falls das hilft).
TPageCollection = Class(TObject);
private FInnerList: TList; x: Double; // ...; // ...; public procedure Add; // ...; // ...; end; Lösen wir uns mal von dem TImage. Ich habe eben mal schnell eine Demo erstellt:
Delphi-Quellcode:
Wie stelle ich jetzt eine Kopie von TKontaktCollection her mitsamt der inneren List? Das ist das Problem. Den bisherigen Code hab eich leider nicht ganz verstanden, weil es doch irgendwie immer etwas durcheinander ging.
unit Adressen;
interface uses Classes; type TKontakt = class(TObject) private FName: String; FAlter: Integer; function GetAlter: Integer; function GetName: String; procedure SetAlter(const Value: Integer); procedure SetName(const Value: String); public property Name: String read GetName write SetName; property Alter: Integer read GetAlter write SetAlter; end; TKontaktCollection = class(TObject) private FInnerList: TList; function GetItem(Index: Integer): TKontakt; procedure SetItem(Index: Integer; const Value: TKontakt); public constructor Create; destructor Destroy; override; procedure Add(Item: TKontakt); function Count: Integer; property Items[Index: Integer]: TKOntakt read GetItem write SetItem; end; implementation { TKontakt } function TKontakt.GetAlter: Integer; begin Result := FAlter; end; function TKontakt.GetName: String; begin Result := FName; end; procedure TKontakt.SetAlter(const Value: Integer); begin FAlter := Value; end; procedure TKontakt.SetName(const Value: String); begin FName := Value; end; { TCollection } procedure TKontaktCollection.Add(Item: TKontakt); begin FInnerList.Add(Item); end; function TKontaktCollection.Count: Integer; begin Result := FInnerLIst.Count; end; constructor TKontaktCollection.Create; begin inherited; FInnerList := TLIst.Create; end; destructor TKontaktCollection.Destroy; var i : Integer; begin if FInnerList.Count > 0 then begin for i := FInnerList.Count - 1 to 0 do begin TObject(FInnerList.Items[i]).Free; end; end; inherited; end; function TKontaktCollection.GetItem(Index: Integer): TKontakt; begin Result := FInnerList.Items[Index]; end; procedure TKontaktCollection.SetItem(Index: Integer; const Value: TKontakt); begin FInnerList.Items[Index] := Value; end; end. (Im Anhang das gesamte Projekt.) |
Re: Objekt kopieren
Hier die zwei notwendigen Methoden, allerdings ungetestet und ohne, dass ich mir das Projekt angesehen habe:
Delphi-Quellcode:
procedure TKontakt.Assign(Source: TKontakt);
begin Name := Source.Name; Alter := Source.Alter; end; procedure TKontaktCollection.Assign(source: TKontaktcollection); var i: Integer; kontakt: TKontakt; begin clear; for i := 0 to source.count-1 do begin kontakt := Add(TKontakt.Create); kontakt.Assign(source.Items[i]); end; end; |
Re: Objekt kopieren
Liste der Anhänge anzeigen (Anzahl: 1)
Ich glaube ich habs:
Delphi-Quellcode:
Und:
procedure TKontakt.Assign(Source: TKontakt);
begin Name := Source.Name; Alter := Source.Alter; end;
Delphi-Quellcode:
Der Test:
procedure TKontaktCollection.Assign(Source: TKontaktCollection);
var i: Integer; kontakt: TKontakt; begin for i := 0 to source.count-1 do begin kontakt := TKontakt.Create; kontakt.Assign(source.Items[i]); Add(kontakt); end; end;
Delphi-Quellcode:
und:
procedure TForm1.Button2Click(Sender: TObject);
var TempCollection: TKontaktCollection; i: Integer; begin TempCollection := TKontaktCollection.Create; try TempCollection.Assign(Adressen); for i := 0 to TempCollection.Count - 1 do begin TempCollection.Items[i].Name := TempCollection.Items[i].Name + ' ist doof.'; ListBox2.Items.Add(TempCollection.Items[i].Name); end; finally TempCollection.Free; end; end;
Delphi-Quellcode:
Die TempCollection wird am Ende der Procedure ja freigegeben. Wären jetzt nur Pointer in der Liste, würde Prozedur UpdateLB1 gar nichts mehr ausgeben - tut sie aber. Ergo wurden die Objekte kopiert und nicht nur die Pointer. Oder sehe ich das falsch?
procedure TForm1.UpdateLB1;
var i: Integer; begin Listbox1.Clear; for i := 0 to Adressen.Count - 1 do ListBox1.Items.Add(Adressen.Items[i].Name + ', ' + IntToStr(Adressen.Items[i].Alter)); end; Im Anhang das ganze Projekt. |
Re: Objekt kopieren
Zitat:
Delphi-Quellcode:
procedure TKontakt.Assign(Source: TPersistent);
begin if Source is TKontakt then begin Name := TKontakt(Source).Name; Alter := TKontakt(Source).Alter; end // weitere (fiktive) Klasse, die zugewiesen werden könnte else if Source is TPerson then begin Name := TPerson(Source).FirstName + ' ' + TPerson(Source).LastName; Alter := round((now - TPerson(Source).BirthDate) / 365.0); end // Wichtig!! wenn mir die Source-Klasse nicht bekannt ist, inherited aufrufen else inherited; end; |
Re: Objekt kopieren
Jupp. Es fehlen zwei Zeilen (Source is TKontakt und inherited), das habe ich mir mal schnell gespart, da eh nichts anderes da ankommen kann. ;)
Aber ich habe das dumpfe Gefühl bei meiner TIMageEnVect-Komponente kopiert Assign nichts, so dass ich alles selber von Hand kopieren muss. :? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:55 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