长话短说:下面这段代码在 Delphi 10.1 Berlin (Update 2) 中无法编译。
interface
uses
System.Classes, System.SysUtils;
type
TTest = class(TObject)
public
function BuildComponent<T: TComponent>(const AComponentString: String): T;
end;
TSomeComponent = class(TComponent)
public
constructor Create(AOwner: TComponent; const AString: String); reintroduce;
end;
implementation
{ TTest }
function TTest.BuildComponent<T>(const AComponentString: String): T;
begin
if T = TSomeComponent then
Result := TSomeComponent.Create(nil, AComponentString)
else
Result := T.Create(nil);
end;
{ TSomeComponent }
constructor TSomeComponent.Create(AOwner: TComponent; const AString: String);
begin
inherited Create(AOwner);
end;
编译器发出了几个错误信息:
-
E2015: 操作符不适用于此操作数类型
在代码行
if T = TSomeComponent then
上和 -
E2010 不兼容的类型 - 'T' 和 'TSomeComponent'
在代码行
Result := TSomeComponent.Create(nil, AComponentString)
上。
为了避免这些问题,我可以进行强制类型转换,如 #1 中的 TClass(T)
(参见LU RD在此处的答案,尽管它已经被说过这个bug已经在XE6中修复了),以及 #2 中的 T(TSomeComponent.Create(nil, AComponentString))
。虽然如此,但是使用显式类型转换让我感到不舒服。
有没有更好的方法?编译器难道不能识别T
是TComponent
类型吗,因为我明确地约束了它吗?
起初,我试图像接口一样声明泛型函数的实现:
function TTest.BuildComponent<T: TComponent>(const AComponentString: String): T;
但是这最终导致了错误
E2029: 期望使用 ','、';' 或 '>',但发现了 ':'