我希望为类型Integer和string绑定类型T:
interface
type
MyFactory<T> = class
public
function createGenerator<T:Integer,string>:IGenerator<T>;
end;
但编译器给出:&#39;(..)E2510 Type&#39; Integer&#39;不是一个有效的约束&#39;。如何将类型T限制为整数或字符串?或者这是一个问题,因为我使用的是序数类型?
答案 0 :(得分:8)
Delphi泛型不支持序数或字符串类型约束。
只允许约束
Delphi Constraints in Generics
我只能猜到你想要完成什么,但是下面的代码可能会给你一些想法
IGenerator<T> = interface
function Generate: T;
end;
TStringGenerator = class(TInterfacedObject, IGenerator<string>)
public
function Generate: string;
end;
TIntegerGenerator = class(TInterfacedObject, IGenerator<integer>)
public
function Generate: integer;
end;
MyFactory<T> = class
public
class function createGenerator<T>: IGenerator<T>;
end;
class function MyFactory<T>.createGenerator<T>: IGenerator<T>;
var
gs: IGenerator<string>;
gi: IGenerator<integer>;
begin
if TypeInfo(T) = TypeInfo(string) then
begin
gs := TStringGenerator.Create;
Result := IGenerator<T>(gs);
end
else
if TypeInfo(T) = TypeInfo(integer) then
begin
gi := TIntegerGenerator.Create;
Result := IGenerator<T>(gi);
end
else Result := nil;
end;
function TIntegerGenerator.Generate: integer;
begin
Result := 10;
end;
function TStringGenerator.Generate: string;
begin
Result := 'abc';
end;
var
i: integer;
s: string;
i := MyFactory<integer>.createGenerator<integer>.generate;
s := MyFactory<string>.createGenerator<string>.generate;
也可以使用 TTypeKind代替TypeInfo
来确定类型。主要区别在于TypeInfo
为您提供了确切使用的类型,而TTypeKind
涵盖了属于特定类别的所有类型。虽然TTypeKind
提供了更大的灵活性,但如果代码依赖于类型转换,则应谨慎使用。例如,tkInteger
涵盖了integer
和byte
类型,而类型转换可能会导致错误。
class function MyFactory<T>.createGenerator<T>: IGenerator<T>;
var
gs: IGenerator<string>;
gi: IGenerator<integer>;
begin
case PTypeInfo(TypeInfo(T)).Kind of
tkUString :
begin
gs := TStringGenerator.Create;
Result := IGenerator<T>(gs);
end;
tkInteger :
begin
gi := TIntegerGenerator.Create;
Result := IGenerator<T>(gi);
end
else Result := nil;
end;
end;