![]() |
Delphi-Version: XE
Gleichnamige Eigenschaft in verschiedenen Klassen ansprechen
Hallo,
ich suche nach einer Möglichkeit, wie ich auf eine gleichnamige Eigenschaft, z.B. das Feld "Bezeichnung" in verschiedenen Klassen zugreifen kann. Derzeit habe ich es so gelöst:
Delphi-Quellcode:
Das ist aber bei umfangreichen Arbeiten mit der Klasse aufwändig, da alles doppelt implementiert ist. Im realen Fall sind es auch mehere Eigenschaften die verwendet werden. Möglichkeit wäre natürlich, diese Eienschaften in eine gemeinsame Basisklasse zu legen, dummerweise ist diese aber schon definiert und wird beliebig oft für anders verwendet wo diese Eigenschaften nicht benötigt werden.
var
lObject: TObject; begin lObject := GetObject(ID); // Kann ein Verweis auf TClass_1 oder TClass_2 zurückgeben if assigned(lObject) then begin if lObject is TClass_1 then with lObject as TClass_1 do Text := Bezeichnung else if lObject is TClass_2 then with lObject as TClass_2 do Text := Bezeichnung; end; end; Gibt es eine Möglichkeit ohne die Klassenstruktur zu ändern? Danke Gerd |
AW: Gleichnamige Eigenschaft in verschiedenen Klassen ansprechen
Eine einfache OOP Lösung gibt es nicht - sobald man mit "is" arbeiten muss, hat man schon den goldenen Pfad verlassen.
Daher würde ich nicht versuchen, eine nicht vorhandene Basisklasse durch eher "kosmetische" Tricks im Sourcecode auszubügeln (class helper oder RTTI). Eher würde ich explizit die verschiedenen Klassen auch mit verschiedenen Methoden behandeln, die dürfen in Delphi über overload ja auch gleiche Namen haben.
Delphi-Quellcode:
var
lObject: TObject; Class1Obj: TClass_1; Class2Obj: TClass_2; begin lObject := GetObject(ID); // Kann ein Verweis auf TClass_1 oder TClass_2 zurückgeben if assigned(lObject) then begin if lObject is TClass_1 then begin Class1Obj := lObject as TClass_1; DoSomethingWith(Class1Obj); end else if if lObject is TClass_2 then begin Class2Obj := lObject as TClass_2; DoSomethingWith(Class2Obj); end end; end; procedure DoSomethingWith(const Obj: TClass_1); overload; begin ... end; procedure DoSomethingWith(const Obj: TClass_2); overload; begin ... end; |
AW: Gleichnamige Eigenschaft in verschiedenen Klassen ansprechen
Wäre das nicht ein klassischer Anwendungsfall für Interfaces?
|
AW: Gleichnamige Eigenschaft in verschiedenen Klassen ansprechen
1) Interfaces
Im Grunde ist das ein klassischer Fall für Interfaces. ![]() ![]() Allerdings verursacht das etwas Mehrarbeit und man muss überlegen, ob man sich auf die Referenzzählung einlassen will oder nicht. Man muss sich auf jeden Fall damit auseinandersetzen, wann man mit dem Interface arbeitet und wann mit der Klasse. 2) Basisklasse Evtl. ist es ja möglich, eine BasisklasseMitDerEigenschaft einzuführen, von der dann - nur diese beiden - Klassen abgeleitet werden. Das wäre wohl der einfachste Fall. Scheint aber wohl hier nicht möglich zu sein. 3) RTTI Man könnte das vorliegende Objekt mit der RTTI auch untersuchen, ob es die bestimmte Eigenschaft besitzt und diese Eigenschaft dann weiter benutzen (So ähnlich aObject.PropertyByName sozusagen.) Das bringt auch einen gewissen Aufwand mit sich und ist ggf. nicht sehr performant. 4) casten Wie im Ausgangspost angegeben. Wenn das im Projekt nur an einigen Stellen und für wenige Klassen benötigt wird, ist das sicherlich (wenn 2) nicht geht) die einfachste Lösung. Etwas Schreibarbeit verursachen alle Lösungen. Das Casten der Objekte ist aber wohl die einfachste mit den geringsten Auswirkungen auf das Projekt. (nebenbei: Auf das with würde ich dort verzichten und lokale Variablen einführen, da das m.E. übersichtlicher ist) |
AW: Gleichnamige Eigenschaft in verschiedenen Klassen ansprechen
Das hört sich so an als seinen wie schon erwähnt Interfaces für dich die ideale Lösung. ;-)
Da du die Referenzzählung wohl kaum verwenden möchtest, kannst du die obersten Klassen einfach von TSingletonImplementation ableiten.
Delphi-Quellcode:
uses
System.Generics.Defaults; type IExample = interface ['{8634FA7C-AA68-43B9-BEDA-2A64E3467F5C}'] property Text... end; TExampleClass = class(TSingletonImplementation, IExample) property Text... end; if Supports(lObject, IExample, Example) then Example.Text := NewText; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:38 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