无法编译受约束的泛型方法

Cannot compile constrained generic method

长话短说:以下代码无法在 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;

编译器发出几条错误消息:

  1. E2015: Operator not applicable to this operand type

    线上 if T = TSomeComponent then

  2. E2010 Incompatible types - 'T' and 'TSomeComponent'

    线上 Result := TSomeComponent.Create(nil, AComponentString).

为了避免这些问题,我可以按照 LU RD's answer here 中的描述施放 TClass(T)(对于 #1)(尽管据说这个错误已经在 中得到修复) XE6)和T(TSomeComponent.Create(nil, AComponentString))(对于#2)。虽然,我对使用显式类型转换感到不舒服。

有什么更好的方法吗?编译器不应该识别 TTComponent 类型因为我明确地限制了它吗?


起初,我尝试像声明接口一样声明泛型函数的实现:

function TTest.BuildComponent<T: TComponent>(const AComponentString: String): T;

但这以错误告终

E2029: ',', ';' or '>' expected but ':' found

这不会在我遇到的任何版本的 Delphi 中编译。您需要进行一些转换才能说服编译器编译它:

function TTest.BuildComponent<T>(const AComponentString: String): T;
begin
  if TClass(T) = TSomeComponent then
    Result := T(TSomeComponent.Create(nil, AComponentString))
  else
    Result := T(TComponentClass(T).Create(nil));
end;

也就是说,我想我可能更喜欢:

if TClass(T).InheritsFrom(TSomeComponent) then

代替相等性测试。

即便如此,尝试将具有不同参数的新构造函数拼接到基于虚拟构造函数的 class 对我来说仍然是灾难的根源。