Longue histoire courte: Le morceau de code suivant ne compile pas dans Delphi 10.1 Berlin (mise à jour 2).Impossible de compiler la méthode générique contrainte
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;
Plusieurs messages d'erreur sont émis par le compilateur:
-
E2015: Opérateur non applicable à ce type d'opérande
en ligne
if T = TSomeComponent then
et -
E2010 types incompatibles - 'T' et 'TSomeComponent'
en ligne
Result := TSomeComponent.Create(nil, AComponentString)
.
Pour contourner ceux-ci, je pourrais jeter TClass(T)
(pour n ° 1), comme décrit dans LU RD's answer here (malgré il est dit, que ce bug a déjà été corrigé dans XE6) et T(TSomeComponent.Create(nil, AComponentString))
(pour # 2). Bien que, je me sens mal à l'aise en utilisant le moulage de type explicite.
Y a-t-il un meilleur moyen? Est-ce que le compilateur ne devrait pas reconnaître que T
est de type TComponent
parce que je l'ai contraint explicitement?
Au début, j'ai essayé de déclarer la mise en œuvre de la fonction générique comme son interface:
function TTest.BuildComponent<T: TComponent>(const AComponentString: String): T;
Mais cela a fini avec l'erreur
E2029: », '' " ou '>' attendu mais ':' trouvé
"Le compilateur ne devrait-il pas reconnaître que T est de type TComponent parce que je l'ai contraint explicitement?" Non, ça ne va pas. Une contrainte générique ne résout pas le type. Il aide simplement le compilateur * à empêcher * d'utiliser le type ou la procédure générique avec des types autres que ceux de la contrainte. Voir ma réponse: https://stackoverflow.com/questions/43679740/test-if-an-interface-equals-a-type-parameter/43681952#43681952 –