Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Kopie eines Klassenobjekts erstellen (https://www.delphipraxis.net/200078-kopie-eines-klassenobjekts-erstellen.html)

DieDolly 17. Mär 2019 18:01

Kopie eines Klassenobjekts erstellen
 
Zu aller erst möchte ich auf diese Seite verweisen auf die ich bei meiner Googlesuche gestoßen bin.
http://forums.devshed.com/delphi-pro...le-449161.html

Da habe ich jetzt die Info her, dass man mit Assign() eine Kopie von TPersistent-Objekten erstellen kann, es sei denn man hat eine eigene Klassenimplementierung / ein eigenes TObject.
Solche Objekte haben keine Assign-Methodik und man muss sie selber implementieren.

Ich konnte in der VCL keinen Code finden der mir eine Art Grundlage gibt, auf die ich aufbauen kann.
Könnt ihr mir helfen?

Mein Klassenobjekt ist so deklariert
Delphi-Quellcode:
TMyObject= class(TObject)
Oder ist es am einfachsten von TPersistent abzuleiten statt von TObject?

dummzeuch 17. Mär 2019 18:14

AW: Kopie eines Klassenobjekts erstellen
 
Beispiele sind TFont oder TStringList.

haentschman 18. Mär 2019 05:47

AW: Kopie eines Klassenobjekts erstellen
 
Moin...:P
Delphi-Quellcode:
class function TSEAMToolsJson.ObjectCopy(aValue: TObject): TObject;
var
  MarshalObj: TJSONMarshal;
  UnMarshalObj: TJSONUnMarshal;
  JSONValue: TJSONValue;
begin
  Result := nil;
  MarshalObj := TJSONMarshal.Create;
  try
    UnMarshalObj := TJSONUnMarshal.Create;
    try
      JSONValue := MarshalObj.Marshal(aValue);
      try
        if Assigned(JSONValue) then
          Result := UnMarshalObj.Unmarshal(JSONValue);
      finally
        JSONValue.Free;
      end;
    finally
      UnMarshalObj.Free;
    end;
  finally
    MarshalObj.Free;
  end;
end;
...fertsch. :P

Hinweis: bei Problemen siehe https://www.delphipraxis.net/199022-...agedialog.html

Sherlock 18. Mär 2019 07:52

AW: Kopie eines Klassenobjekts erstellen
 
Und wie performant ist das mit dem JSON hin und her konvertieren?
Es sieht allerdings deutlich aufgeräumter aus als
Delphi-Quellcode:
procedure TCTGNote.Assign(Source: TCTGNote);
begin
  if Assigned(Source) and (Source is TCTGNote) then
  begin
    Self.fID := Source.fID;
    Self.fTraceID := Source.fTraceID;
    Self.fEntryDate := Source.fEntryDate;
    Self.fNote := Source.fNote;
    Self.fUserName := Source.fUserName;
    Self.fUserID := Source.fUserID;
    Self.fNoteType := Source.fNoteType;
  end;
end;
Sherlock

haentschman 18. Mär 2019 07:57

AW: Kopie eines Klassenobjekts erstellen
 
Zitat:

Es sieht allerdings deutlich aufgeräumter aus als
..erst Recht mit Datenobjekten mit mehr als 100 Properties. :P

Stevie 18. Mär 2019 08:44

AW: Kopie eines Klassenobjekts erstellen
 
Brrr, bloß nich über JSON, das wird doch jede zweite Version erstmal für 1 oder 2 Updates kaputt gemacht...

TiGü 18. Mär 2019 09:06

AW: Kopie eines Klassenobjekts erstellen
 
Wenn überschaubare Anzahl an Feldern nehme eine eigene Methode zum Kopieren.

Vorteil:
- am Performantesten
- Prüfungen zur Laufzeit möglich
- Debugging ist einfach

Nachteil:
- ggf. viel Quelltext

Wenn der Aufwand für viele Felder zu hoch ist, dann nehme einen Ansatz per RTTI (Google: "delphi copy object rtti").

QuickAndDirty 18. Mär 2019 09:13

AW: Kopie eines Klassenobjekts erstellen
 
@OP
Wenn man eine eigenes Objekt kopierbar habe will implemtiert man die Methoden Assign und AssignTo selbst.
Wenn man ein Objekt von TPersistent ableitet muss man Methoden zum Speichern(als stream/Datei) und Lesen(von Stream/Datei) des Objekts implemtieren.

Es ist mit hilfe der sogenannten RTTI und vor allem der Advanced-RTTI Unterstützung aktueller Delphi Versionen möglich eine Objekt-Kopier-Funktion zu schreiben, welche ziemlich viele Arten von einfachen Objekten kopiert.

Es gibt dabei natürlich einiges zu bedenken! Wenn Objekte welche ihrerseits Objekte Referenzieren kopiert werden sollen muss geklärt sein ob es sich bei diesen Referenzen um Assoziationen oder Compositionen handelt. Da RTTI nicht preisgibt ob ein Attribut vom Typ Objekt-Referenz durch eine Methode dieses Objekts erzeugt und zerstört wird.

Es bedürfte also eines Markers zur Unterscheidung von Assoziation und Composition im Aufbau der Klassen...und das wird bei den Mitgelieferten klassen nicht bereits unterschieden. Kann aber für eigene klassen umgesetzt werden.

Klassen die reine Name-Wert-Paare sind lassen sich am leichtesten über RTTI kopieren.

Leider bläht RTTI das Kompilat auf! Und man muss manchmal dafür sorgen das RTTI für eigene Klassen global zur Verfügung stehen.
Bei Komplexeren klassen muss man evtl. beim kopieren auf zirkuläre referenzen prüfen (siehe -> durchsuchen eines Graphen aka DFS vs BFS)

DieDolly 18. Mär 2019 10:06

AW: Kopie eines Klassenobjekts erstellen
 
Zitat:

Wenn man eine eigenes Objekt kopierbar habe will implemtiert man die Methoden Assign und AssignTo selbst.
Wenn man ein Objekt von TPersistent ableitet muss man Methoden zum Speichern(als stream/Datei) und Lesen(von Stream/Datei) des Objekts implemtieren.
Die Daten lade und speichere ich eh selber mit extra Quelltext. Was anderes käme mir gar nicht in den Sinn.

Ist von TPersistent ableiten also gut genug und genau so perfomant wie TObject? Es geht hier um das Erstellen von circa 150 bis 200 Klassenobjekten bei Programmstart.
So wie ich das sehe leitet TPersistent am Ende auch wieder nur von TObject ab und fügt 7 neue Prozeduren und Funktionen ein.

Komplizierte Objekttypen habe ich nicht. Strings, Integer und eindimensionale Arrays (String, Integer und einfache Enums).

Stevie 18. Mär 2019 10:09

AW: Kopie eines Klassenobjekts erstellen
 
Wenn die Klassen, die kopiert werden sollen, so umfangreich und zahlreich werden, kann man auch Code generieren - entweder durch Tools wie DelphiAST, oder man packt die Klassen in ein Projekt, in denen das anhand deren RTTI passiert. Dann hat man die Vorteile von beiden Herangehensweisen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:21 Uhr.
Seite 1 von 3  1 23      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz