Einzelnen Beitrag anzeigen

Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.016 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#22

AW: Generisches Alias von TFrame

  Alt 16. Mai 2018, 17:05
Ja, irgendwo im generischen Code muss dann eine if-then-else "Leiter" wie zuvor schon gezeigt rein.
Ohne das jetzt näher analysiert zu haben - wäre das nicht was für das Visitor-Pattern?
Dafür müsste man der overload resolution in Generics vertrauen, und das tu ich nicht.

Edit: Hast recht, ich hab verkehrt herum gedacht, aber so sollte das funktionieren (auf Erstellen von Objekten wo nicht benötigt hab ich für das Beispiel verzichtet):

Delphi-Quellcode:
{$APPTYPE CONSOLE}

type
  TFruchtKorbFactory = class;

  TFrucht = class
    function GibFruchtKorb(const factory: TFruchtKorbFactory): TObject; virtual; abstract;
  end;

  TBanane = class(TFrucht)
    function GibFruchtKorb(const factory: TFruchtKorbFactory): TObject; override;
  end;

  TApfel = class(TFrucht)
    function GibFruchtKorb(const factory: TFruchtKorbFactory): TObject; override;
  end;

  TFruchtKorbFactory = class
    function CreateInstance(const banane: TBanane): TObject; overload;
    function CreateInstance(const apfel: TApfel): TObject; overload;
  end;

  TGenericDings<T: TFrucht, constructor> = class
    procedure Wuppdi;
  end;

{ TBanane }

function TBanane.GibFruchtKorb(const factory: TFruchtKorbFactory): TObject;
begin
  Result := factory.CreateInstance(Self);
end;

{ TApfel }

function TApfel.GibFruchtKorb(const factory: TFruchtKorbFactory): TObject;
begin
  Result := factory.CreateInstance(Self);
end;

{ TFruchtKorbFactory }

function TFruchtKorbFactory.CreateInstance(const apfel: TApfel): TObject;
begin
  Writeln('erstelle fruchtkorb für apfel');
end;

function TFruchtKorbFactory.CreateInstance(const banane: TBanane): TObject;
begin
  Writeln('erstelle fruchtkorb für banane');
end;

{ TGenericDings<T> }

procedure TGenericDings<T>.Wuppdi;
var
  frucht: T;
  factory: TFruchtKorbFactory;
begin
  frucht := T.Create; // das hier wird für den virtual dispatch von GetWhatever benötigt
  frucht.GibFruchtKorb(factory);

  // Was hier nicht gehen würde wäre: factory.CreateInstance(frucht);
end;

var
  apfeldings: TGenericDings<TApfel>;
  bananendings: TGenericDings<TBanane>;
begin
  apfeldings.Wuppdi;
  bananendings.Wuppdi;
end.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie (16. Mai 2018 um 17:30 Uhr)
  Mit Zitat antworten Zitat