Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Gleichnamige Eigenschaft in verschiedenen Klassen ansprechen (https://www.delphipraxis.net/189955-gleichnamige-eigenschaft-verschiedenen-klassen-ansprechen.html)

norwegen60 12. Aug 2016 13:03

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:
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;
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.

Gibt es eine Möglichkeit ohne die Klassenstruktur zu ändern?

Danke
Gerd

mjustin 12. Aug 2016 13:10

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;

DeddyH 12. Aug 2016 13:18

AW: Gleichnamige Eigenschaft in verschiedenen Klassen ansprechen
 
Wäre das nicht ein klassischer Anwendungsfall für Interfaces?

stahli 12. Aug 2016 13:24

AW: Gleichnamige Eigenschaft in verschiedenen Klassen ansprechen
 
1) Interfaces

Im Grunde ist das ein klassischer Fall für Interfaces.
https://development.mwcs.de/tutinterfaces.html
http://www.delphipraxis.net/183702-i...-factorys.html

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)

jaenicke 12. Aug 2016 13:25

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 13:21 Uhr.

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