在Delphi中测试泛型的类型

13
我希望有一种方式可以在Delphi中编写以下类似的函数。
procedure Foo<T>;
begin
    if T = String then
    begin
        //Do something
    end;

    if T = Double then
    begin
        //Do something else
    end;
end;

ie: 我希望根据通用类型能够做不同的事情

我试过使用 System 中的 TypeInfo,但这似乎只适用于对象而不是通用类型。

我甚至不确定在Pascal中是否可能实现这一点。


1
GetTypeKind应该这样做。请参见http://delphisorcery.blogspot.de/2014/10/new-language-feature-in-xe7.html。 - Uli Gerhardt
你可以使用变量吗? - whosrdaddy
2个回答

14
从XE7开始,您可以使用GetTypeKind函数来查找类型种类。请注意保留HTML标记。
case GetTypeKind(T) of
tkUString:
  ....
tkFloat:
  ....
....
end;

当然,tkFloat 可以识别所有浮点数类型,因此您也可以测试 SizeOf(T) = SizeOf(double)

旧版本的 Delphi 没有 GetTypeKind 内置函数,您必须使用 PTypeInfo(TypeInfo(T)).Kind。使用 GetTypeKind 的优点是编译器能够评估它并优化掉可以被证明未被选中的分支。

但这一切都有些违背了范型的目的,人们会想知道是否存在更好的解决方案来解决您的问题。


2
顺便提一下,我链接了GetTypeKind文档,尽管它没有被记录下来,希望有一天Emba文档能够跟上。 - David Heffernan
1
请注意,如果您想测试 T 是否为 double,那么 if TypeInfo(T) = TypeInfo(double) then ... 也将解析为内置类型,并且不会生成任何代码。 - Johan

11

TypeInfo应该可以正常工作:

type
  TTest = class
    class procedure Foo<T>;
  end;

class procedure TTest.Foo<T>;
begin
  if TypeInfo(T) = TypeInfo(string) then
    Writeln('string')
  else if TypeInfo(T) = TypeInfo(Double) then
    Writeln('Double')
  else
    Writeln(PTypeInfo(TypeInfo(T))^.Name);
end;

procedure Main;
begin
  TTest.Foo<string>;
  TTest.Foo<Double>;
  TTest.Foo<Single>;
end;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接