【问题标题】:How to add type-specific code for generics in Delphi如何在 Delphi 中为泛型添加特定于类型的代码
【发布时间】:2013-07-07 20:17:39
【问题描述】:

是否有任何有效的方法来为 delphi 泛型添加特定于类型的代码? 例如这样的:

function TGT<T>.GetSize(a: T): integer;
begin
  {$IF TypeInfo(T)=TypeInfo(String)}
    result := Length(A);
  {$ELSE}
    result := SizeOf(A);
  {$IFEND}
end;

function TGT<T>.Compare(a,b: T): integer;
begin
  {$IF TypeInfo(T)=TypeInfo(String)}
    result := AnsiCompareText(a,b);
  {$ELSE}
    result := a-b;
  {$IFEND}
end;

所以我需要根据类型以不同的方式实现代码的某些部分。 例如,如果我实现了排序例程,我想使用整数/双精度/等类型的值的直接比较(它比调用像 delphi 的标准通用容器这样的接口方法更有效)和函数 AnsiCompareText 用于字符串类型。

有一些示例如何做到这一点,但所有示例都基于这样的检查:

if TypeInfo(T)=TypeInfo(String) then xxx else if TypeInfo(T)=TypeInfo(Integer) then xxx

这里的问题是 Delphi 只会在运行时检查它,这(再次)不是那么有效。 我想让编译器在编译时进行所有检查,并且只使用特定于所选类型的代码。

【问题讨论】:

    标签: delphi generics


    【解决方案1】:

    嗯,你当然不能指望用条件编译来做这样的事情。请记住,泛型的条件编译是在泛型编译阶段而不是实例化阶段处理的。所以你不能指望用你的条件语句的不同分支来编译不同的实例。

    您当然永远无法让编译器接受 Length(a) 参数化的 a 类型,因为无法指定允许使用 Length 的约束。

    唯一的选择是运行时检查。

    【讨论】:

    • 我知道条件编译并不能解决我的问题,我只是用它来说明。但我希望存在另一种方式。在我看到的所有 Delphi 的泛型中,接口用于完成特定于类型的任务。而且它看起来不像是坚实而清晰的概念,它看起来像是一种黑客或技巧。引入像泛型这样强大的工具似乎很奇怪,但却无法使代码高效。实际上,这意味着对于时间紧迫的任务,即使在像数据排序这样的常见例程中,复制粘贴代码而不是使用泛型会更有效。
    • 您确定在Generics.Defaults 中使用通用比较器接口真的那么慢吗?无论如何,泛型不是模板。它们本质上不如模板。
    • @David,我最近从您那里读到了很多关于“通用编译阶段”的信息。虽然这对我来说很有意义,但这是否记录在某个地方?
    • @iamjoosy 我不这么认为。我在写答案时编造了这个词,我认为这个词!有各种 Emba 博客讨论不同的编译阶段。
    • @David,这当然解释了为什么每个 Generic 类实例化都会创建一个新类,这有时会导致一些意外 - 想想类变量,例如
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多