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.