如何在调用两个(多)层泛型的虚拟方法时删除其他类型参数?

问题描述:

有一个TBaseClassList<T: TBaseClass>类具有虚拟方法DoSomething。我想从TBaseClassList之外的另一个打开构造类型方法调用此方法,并将其后代CallDoSomething。这是我的代码:如何在调用两个(多)层泛型的虚拟方法时删除其他类型参数?

type 
    TBaseClass = class end; 

    TBaseClassList<T: TBaseClass> = class 
    class procedure DoSomething; virtual; abstract; 
    end; 

    TSubClass1 = class(TBaseClass) end; 

    TSubClass1List = class(TBaseClassList<TSubClass1>) 
    class procedure DoSomething; override; 
    end; 

    TDoSomethingCaller = class 
    class procedure CallDoSomething<T: TBaseClass; L: TBaseClassList<T>>; 
    end; 

implementation 

class procedure TSubClass1List.DoSomething; 
begin 
    ShowMessage('TSubClass1List.DoSomething'); 
end; 

class procedure TDoSomethingCaller.CallDoSomething<T, L>; 
begin 
    L.DoSomeThing; 
end; 

initialization 
    TDoSomethingCaller.CallDoSomething<TSubClass1, TSubClass1List>; 
end. 

现在,我正在以正确的方式吗?是否可以仅使用一个类型参数来定义CallDoSomething

CallDoSomething,我试过其他定义是:

方法1:

class procedure CallDoSomething<L: TBaseClassList>; 

我的德尔福不能编译它(我使用的是10.1柏林)。它说:

E2003 Undeclared identifier: 'TBaseClassList'

方法2:

class procedure CallDoSomething<T: TBaseClass>; 
... 
class procedure TDoSomethingCaller.CallDoSomething<T>; 
begin 
    TBaseClassList<T>.DoSomething; 
end; 

它有一个运行时错误:

Project raised exception class EAbstractError with message 'Abstract Error'.

方法3:

class procedure CallDoSomething<L: TSubClass1List>; 

现在我不能拨打CallDoSomethingTSubClass2List

P.S.我甚至不知道如何用文字表达我的问题,因此,对于更好的标题或描述的任何建议将不胜感激。

+0

为什么,如果你只使用一个参数,您传递了两个通用参数,'CallDoSomething'? –

+0

@RemyLebeau因为我是新的泛型:)。我编辑了我的问题,并添加了我试图删除额外参数的内容。 – saastn

这是我会怎么做

type 
    TBaseClass = class 
    end; 

    TBaseClassList = class 
    class procedure DoSomething; virtual; abstract; 
    end; 

    TBaseClassList<T: TBaseClass> = class(TBaseClassList) 
    end; 

    TSubClass1 = class(TBaseClass) 
    end; 

    TSubClass1List = class(TBaseClassList<TSubClass1>) 
    class procedure DoSomething; override; 
    end; 

    TDoSomethingCaller = class 
    class procedure CallDoSomething<L: TBaseClassList>; 
    end; 

implementation 

class procedure TSubClass1List.DoSomething; 
begin 
    inherited; 
    ShowMessage('TSubClass1List.DoSomething'); 
end; 

class procedure TDoSomethingCaller.CallDoSomething<L>; 
begin 
    L.DoSomething; 
end; 

initialization 
    TDoSomethingCaller.CallDoSomething<TSubClass1List>; 

end. 
+0

我应该提到,我首先尝试了这一点。它不在这里编译:'E2003未声明的标识符:'TBaseClassList''。 CallDoSomething“的定义。 – saastn

+1

因为你缺少非通用的'TBaseClassList' - 至少在你的问题的代码。 –

+0

@StefanGlienke我的不好,我必须在这里阅读代码两次。顺便说一下,'PTBaseClassList'的目的是什么? – saastn