Thema: RTTI Problem

Einzelnen Beitrag anzeigen

Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#11

AW: RTTI Problem

  Alt 23. Apr 2024, 12:17
Wie ich schon schrieb halte ich den Ansatz, die über die Properties zu iterieren und diese jeweils zu kopieren, - wenn überhaupt mit vertretbarem Aufwand umsetzbar - für ziemlich aufwändig, fehleranfällig und schlecht wartbar. Immerhin muss bei jedem neuen Property geprüft werden, ob sich das so einfach kopieren lässt und das auch sachlich korrekt durchgeführt wird. Nicht immer enthalten die Properties Strings oder numerische Werte. Klasseninstanzen, Interfaces oder auch Arrays werden so nur als Referenzen und nicht inhaltlich kopiert. Das ist in der Regel bei Arrays und oft bei Klassen gar nicht gewollt. Solche Fälle müssten jeweils gesondert behandelt werden, was bei der RTTI-Lösung den Aufwand beträchtlich steigert.

Den empfohlenen Ansatz hat Frank schon mit TPersistent.Assign und seinem Pendant TPersistent.AssignTo angesprochen. Dieses Verfahren ist schon so alt wie Delphi, wird allgemein verstanden und hat sich bei korrekter Anwendung als stabil erwiesen.

Man kann sich die Implementierung in den simplen Fällen (Strings und numerische Werte) vereinfachen, wenn man die einzelnen Felder hinter den Properties einen record verlagert, der mit einfacher Zuweisung kopiert werden kann. Das deckt die ursprüngliche Absicht zur Vereinfachung der Wartbarkeit bereits ab. Da in dem beschriebenen Fall offenbar mit Interfaces gearbeitet wird, sind sowieso schon Getter und Setter vorhanden, die dann auf die Record-Felder umgeleitet werden. Eine mögliche Implementierung der TPersistent.Assign Ableitung sähe dann, unter der Annahme dass TProduct direkt von TPersistent abgeleitet ist, in etwa so aus:
Delphi-Quellcode:
procedure TProduct.Assign(Source: TPersistent);
begin
  if Source is TProduct then begin
    FData := TProduct(Source).FData;
  end
  else
    inherited;
end;
Bei dem Assign mit einem IProduct als Source wird es etwas komplexer und es bieten sich je nach Gegebenheiten mehrere Lösungsmöglichkeiten an:
  • Man erweitert IProduct um eine entsprechende Methode, die dann in allen Implementierungen entsprechend gefüllt werden muss.
  • Man deklariert ein separates Interface für das Assign, das man dan über Supports abfragt.
  • Wenn sichergestellt ist, dass alle Implementationen von IProduct auf TPersistent aufbauen: Assign(Source as TPersistent);
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat