Einzelnen Beitrag anzeigen

Benutzerbild von Stevie
Stevie

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

AW: Generics: Instanz-Erzeugung in generischer Klasse

  Alt 10. Okt 2011, 08:15
Ich denke mal nicht, denn in der generischen Klasse ist TButton nicht bekannt sondern nur abstrakt als T (irgendwas ab TComponent).
Nachfahren von TComponent können aber auch den Constructor überschreiben:
Delphi-Quellcode:
TMyComponent = class(TComponent)
public
  constructor Create; reintroduce;
end;
und schon gibt es für diese Ableitung kein Create(AOwner:TComponent) mehr.
Das stimmt so nicht ganz. Du kannst immernoch TMyComponent.Create(MyOtherComponent) aufrufen. Zusätzlich sollte man niemals den Konstruktor eines TComponent ohne den Owner überschreiben, denn diesen benutzt auch die IDE, wenn man die Komponente auf dem Form platziert. Auch wenn du keine in der IDE registrierte Komponente baust.

Manchmal muss man, wenn man weiß, dass T von einem bestimmten Typ ist (da man ihn ja als Type constraint angegeben hat) trotzdem noch herumtricksen, da man nicht einfach alle Methoden dieses Typs benutzen kann.

TComponent(T).Create(nil) geht auf jeden Fall nicht.

Das hier geht:

Delphi-Quellcode:
type
  TGenericLink<T: TComponent> = class
  private
    FLink: T;
    function CreateComponent(AClass: TComponentClass): TComponent;
  public
    constructor Create;
    property Link: T read FLink;
  end;

function TGenericLink<T>.CreateComponent(AClass: TComponentClass): TComponent;
begin
  FLink := T(AClass.Create(nil));
end;

constructor TGenericLink<T>.Create;
begin
  CreateComponent(TComponentClass(T));
end;
Im übrigen gibt es mit ziemlicher Sicherheit eine schönere Lösung, als dein Workaround. Vermutlich über RTTI. Sowas in der Art macht Delphi ja bei den Formulardaten, die aus den dfms gelesen werden. Auch da müssen TComponent-Nachfahren dynamisch erzeugt werden, ohne, dass die konkrete Klasse zur Designzeit schon klar wäre.
Delphi macht da nix über RTTI (was das Erzeugen des Objects angeht). Das geht nämlich erst mit der neuen RTTI ab 2010. Vorher gingen nur published Methoden und der Constructor ist nicht published. Es wird also genauso über die TComponentClass gemacht.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat