Delphi泛型函数

5

我希望创建一个通用函数。我对泛型编程还不是很熟悉。 我有三个不同类型的私有列表。我想要一个公共的泛型方法来返回列表中的一个元素。

以下是我的代码。(我已经简化了它)

TFilter = class
private
   FListFilter            : TObjectList<TFilterEntity>;
   FListFilterDate        : TObjectList<TFilterDate>;
   FListFilterRensParam   : TObjectList<TFilterRensParam>;
public
   function yGetFilter<T>(iIndice : integer) : T; 
....
function TFilter .yGetFilter<T>(iIndice : integer) : T; 
begin
    if T = TFilterEntity then
       result := T(FListFilter.Items[iIndice])
    else
       ....
end;

我知道这段代码不能运行,但能否告诉我它是否有可能实现一个功能?


2
这看起来像是泛型的弱化使用。任何时候,如果你不得不包含一个运行时类型测试,那通常意味着设计很差。我怀疑你可以做得更好。 - David Heffernan
1个回答

3

介绍一下泛型参数 T 的一个约束条件,它必须是一个类。

来自文档:

一个类型参数可以被零个或一个类类型约束。与接口类型约束一样,这个声明意味着编译器将要求传递给受限制类型参数的任何具体类型都与约束类兼容。 类型的兼容性遵循面向对象编程的规则:派生类型可以在其祖先类型所需的位置上使用。

更改声明为:

function yGetFilter<T:class>(iIndice : integer) : T;

更新

看起来在XE5及其早期版本中,您将会收到编译器错误:

E2015 运算符不适用于此操作数类型

在这一行代码:

if T = TFilterEntity then

在XE6及以上版本中,这个错误已经被修复。
为了规避此问题,请按照David在评论中所说的操作。
if TClass(T) = TFilterEntity then

你确定函数的约束与类的约束相似吗?我遇到了这个错误:[dcc32 Erreur] YP.Filter.ListFilter.pas(307): E2029 ',', ';' ou '>' attendu(e) mais ':' trouvé(e) - Joc02
+1 但你需要额外的转换 if TClass(T) = TFilterEntity then 来让编译器满意。 - David Heffernan
现在编译器很开心!谢谢。 - Joc02
我也遇到了E2029错误,提示需要使用“,”、“;”或“>”,但实际上却找到了“:”。在我的情况下,我不清楚在哪里添加额外的转换。 - jifb

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