Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Generics // rekursive Typargumente (https://www.delphipraxis.net/187888-generics-rekursive-typargumente.html)

bepe 12. Jan 2016 18:10

Generics // rekursive Typargumente
 
Hallo,

ich hätte da mal was wo ich ein par Denkanstöße benötige. Folgendes Konstrukt ist gegeben:

Delphi-Quellcode:
  IDummy = interface
  ['{F1F27BED-AD34-45FE-A8BB-9F776FB52517}']
  end;

  IItem<T: IDummy; RT: IDummy> = interface(IDummy)
  ['{A0B81638-424C-40E8-80F6-8FFB20CA9E65}']
    function DoIt(AParam: T): RT;

  end;

  IGroup<T: IDummy; RT: IDummy> = interface(IDummy)
  ['{1908848D-964A-4BC4-8EC8-7A0E52ADD532}']
    function CloseGroup: RT;
    function AddGroup: IGroup<T,IGroup<T,RT>>;
    function AddItem: IItem<T,IGroup<T,RT>>;

  end;

  IContainer<T: IDummy> = interface(IDummy)
  ['{DA22B0E3-E682-4ED3-AA30-46B39AE24A90}']
    function AddGroup: IGroup<T,IContainer<T>>;
    function AddItem: IItem<T,IContainer<T>>;

    function Execute: Boolean;

  end;

  TItem<T: IDummy; RT: IDummy> = class(TInterfacedObject, IItem<T,RT>)
  strict private
    FParent: RT;

  public
    constructor Create(AParent: RT);

    function DoIt(AParam: T): RT;

  end;

  TGroup<T: IDummy; RT: IDummy> = class(TInterfacedObject, IGroup<T,RT>)
  strict private
    FParent: RT;

  public
    constructor Create(AParent: RT);

  public
    function CloseGroup: RT;
    function AddGroup: IGroup<T,IGroup<T,RT>>;
    function AddItem: IItem<T,IGroup<T,RT>>;

  end;

  TContainer<T: IDummy> = class(TInterfacedObject, IContainer<T>)
  public
    function AddGroup: IGroup<T,IContainer<T>>;
    function AddItem: IItem<T,IContainer<T>>;

    function Execute: Boolean;

  end;

implementation

{ TItem<T, RT> }

constructor TItem<T, RT>.Create(AParent: RT);
begin
  FParent := AParent;
end;

function TItem<T, RT>.DoIt(AParam: T): RT;
begin
  Result := FParent;
end;

{ TGroup<T, RT> }

function TGroup<T, RT>.AddGroup: IGroup<T, IGroup<T, RT>>;
begin
  Result := TGroup<T,IGroup<T, RT>>.Create(Self); // hier passen die Typen nicht
end;

function TGroup<T, RT>.AddItem: IItem<T, IGroup<T, RT>>;
begin
  Result := TItem<T,IGroup<T, RT>>.Create(Self);
end;

function TGroup<T, RT>.CloseGroup: RT;
begin
  Result := FParent;
end;

constructor TGroup<T, RT>.Create(AParent: RT);
begin
  FParent := AParent;
end;

{ TContainer<T> }

function TContainer<T>.AddGroup: IGroup<T, IContainer<T>>;
begin
  Result := TGroup<T,IContainer<T>>.Create(Self);
end;

function TContainer<T>.AddItem: IItem<T, IContainer<T>>;
begin
  Result := TItem<T,IContainer<T>>.Create(Self);
end;

function TContainer<T>.Execute: Boolean;
begin
  beep;
end;
In
Delphi-Quellcode:
TGroup<T, RT>.AddGroup
passt die erzeugte Gruppe nicht zum Result. Ich kann das Problem zwar fast nachvollziehen aber es reicht noch nicht um eine Lösung zu finden. Kann mich mal jemand in eine Richtung schubsen?

Mein Ansatz darf/kann auch grundlegende Änderungen/Erweiterungen erfahren. Wichtig ist mir nur das Ziel:

Delphi-Quellcode:
var
  tmpContainer: IContainer<IDummy>;
begin
  tmpContainer := TContainer<IDummy>.Create;
  tmpContainer.AddItem.DoIt(nil).
                  AddGroup.AddItem.DoIt(nil).
                           AddItem.DoIt(nil).
                           AddGroup.AddItem.DoIt(nil).
                                  AddItem.DoIt(nil).
                           CloseGroup.
                  CloseGroup.AddItem.DoIt(nil).
               Execute;
Danke.

Mavarik 12. Jan 2016 18:18

AW: Generics // rekursive Typargumente
 
Generisches Interfaces mit GUID?

Und eine T:IDummy als T-Einschränker mit GUID?

Mavarik

bepe 12. Jan 2016 18:51

AW: Generics // rekursive Typargumente
 
STRG+SHIFT+G ist wie STRG+S einfach ein antrainierter Reflex :-D

Macht aber, in dem Fall, keinen Unterschied. Das Problem ist ja, das die generischen Typen zur Laufzeit nicht mehr generisch sind. Aus der Ecke dürfte mein Problem kommen.

Mavarik 12. Jan 2016 19:17

AW: Generics // rekursive Typargumente
 
Dann bekommst Du aber Objecte mit gleicher GUID bei unterschiedlichen Typen, oder?

bepe 12. Jan 2016 19:28

AW: Generics // rekursive Typargumente
 
Ich hab keine Ahnung was Delphi da macht. Hab deinen Einwand gelesen und war spontan irritiert. Man könnte eigentlich erwarten, dass der Compiler zu meinem Unsinn wenigstens einen Hinweis ausgibt.

Habe die GUIDs entfernt und es scheint keinen Unterschied zu machen.

Mavarik 12. Jan 2016 20:35

AW: Generics // rekursive Typargumente
 
Zitat:

Zitat von bepe (Beitrag 1326785)
Ich hab keine Ahnung was Delphi da macht. Hab deinen Einwand gelesen und war spontan irritiert. Man könnte eigentlich erwarten, dass der Compiler zu meinem Unsinn wenigstens einen Hinweis ausgibt.

Habe die GUIDs entfernt und es scheint keinen Unterschied zu machen.

Vielleicht blicke ich es gerade nicht...

Warum die Vererbung von IDummy?

bepe 13. Jan 2016 06:17

AW: Generics // rekursive Typargumente
 
Zitat:

Zitat von Mavarik (Beitrag 1326788)
Warum die Vererbung von IDummy?

In diesem Beispiel bewirkt es nichts. Es soll nur die Verwandtschaftsverhältnisse innerhalb der echten Klassen verdeutlichen. Es gibt eine ganze Reihe von Klassen die durch Module (u.a. auch Plugins/BPLs) erweitert und ersetzt werden können.
Alle Klassen, dieses Themenkomplexes, stammen von bzw. implementieren ein gemeinsames Ur-Interface. Einfach damit die Verwaltungsroutinen (laden von Modulen, registrieren der Klassen und bereitstellen von Instanzen) etwas zum "anfassen" haben.

Als Typargument wird IDummy nicht verwendet sondern ein Nachfahre, welcher die Mindestanforderungen erfüllt. Es gibt auch keine Container-, Gruppen- oder Itemklassen. Es gibt aber Klassen die, neben ihrer eigentlichen Bestimmung, ihrem primär Interface, zusätzlich eines (oder eine Kombination) der hier gezeigten Interfaces implementieren.

Das ganze ist also noch ein gutes Stück komplexer. Hatte gestern Abend das Gefühl, den ganzen Tag in Brainfuck programmiert zu haben :wink:


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:42 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