Delphi - 泛型类型约束序数类型
Delphi - Generics type constraint ordinal types
我想为整数和字符串类型绑定类型 T:
interface
type
MyFactory<T> = class
public
function createGenerator<T:Integer,string>:IGenerator<T>;
end;
但编译器给出:“(..) E2510 类型 'Integer' 不是有效约束”。如何将类型 T 限制为整数或字符串?或者这是一个问题,因为我使用的是序数类型?
Delphi 泛型不支持序号或字符串类型约束。
唯一允许的约束是
- 零种、一种或多种接口类型
- 零个或一个 class 类型
- 保留字"constructor"、"class"或"record"
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;
我想为整数和字符串类型绑定类型 T:
interface
type
MyFactory<T> = class
public
function createGenerator<T:Integer,string>:IGenerator<T>;
end;
但编译器给出:“(..) E2510 类型 'Integer' 不是有效约束”。如何将类型 T 限制为整数或字符串?或者这是一个问题,因为我使用的是序数类型?
Delphi 泛型不支持序号或字符串类型约束。
唯一允许的约束是
- 零种、一种或多种接口类型
- 零个或一个 class 类型
- 保留字"constructor"、"class"或"record"
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;