【发布时间】:2017-06-01 13:08:41
【问题描述】:
长话短说:以下代码无法在 Delphi 10.1 Berlin(更新 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).
为了规避这些,我可以转换TClass(T)(用于#1),如LU RD's answer here 中所述(尽管据说这个错误已经在XE6 中修复),并且T(TSomeComponent.Create(nil, AComponentString))(对于#2)。虽然,我对使用显式类型转换感到不舒服。
有没有更好的办法?编译器不应该认识到T 是TComponent 类型,因为我明确限制了它吗?
起初,我尝试将泛型函数的实现声明为接口:
function TTest.BuildComponent<T: TComponent>(const AComponentString: String): T;
但这以错误告终
E2029: ',', ';'或 '>' 预期但 ':' 找到
【问题讨论】:
-
“编译器不应该识别出 T 是 TComponent 类型,因为我明确地限制了它吗?”不,不会的。泛型约束不解析类型。它只是帮助编译器防止使用非约束类型的泛型类型或过程。看我的回答:stackoverflow.com/questions/43679740/…
标签: delphi generics constraints delphi-10.1-berlin generic-constraints