为什么TGeneric <数据库>和TGeneric <后代>不兼容的类型?
-
18-09-2019 - |
题
我已经使用在2010年的Delphi泛型的开始,但是我有编译这段代码时的问题:
TThreadBase = class( TThread )
...
end;
TThreadBaseList<T: TThreadBase> = class( TObjectList<T> )
...
end;
TDataProviderThread = class( TThreadBase )
...
end;
TDataCore = class( TInterfacedObject, IDataCore )
private
FProviders: TThreadBaseList<TDataProviderThread>;
...
end;
然后,我有一些嵌套的过程:
procedure MakeAllThreadsActive(aThreads: TThreadBaseList<TThreadBase>);
begin
...
end;
最后,我想调用在TDataCore类的代码此嵌套过程:
MakeAllThreadsActive(FProviders);
但是编译器不希望编译它和它说(“<>”括号被取代“()”):
[DCC错误] LSCore.pas(494):E2010不兼容的类型: 'TThreadBaseList(TThreadBase)' 和 'TThreadBaseList(TDataProviderThread)'
虽然TDataProviderThread是TThreadBase的后代我不理解它。
我具有由硬铸字进行修复:
MakeAllThreadsActive(TThreadBaseList<TThreadBase>(FProviders));
有谁知道为什么编译器说这个错误?
解决方案
TDataProviderThread是TThreadBase的后代,但TThreadBaseList<TDataProviderThread>
不是TThreadBaseList<TThreadBase>
的后代。这不是继承,这就是所谓的协的东西,虽然这似乎直觉一样的东西,它不是,它有单独的支持。目前,德尔福不支持它,但希望它会在将来的版本。
下面是对协方差问题的根本原因是:如果函数你将它传递给期待TThreadBase对象的列表,而且你通过它TDataProviderThread对象的列表,没有什么可以阻止它调用。新增并坚持一些其他TThreadBase对象到这不是一个TDataProviderThread以及现在你已经有了各种各样的难看问题一览表。您需要特殊的技巧从编译器,以确保这是不可能发生的,否则你失去了你的类型安全。
编辑:这是给你一个可能的解决方案:请MakeAllThreadsActive到一个通用的方法,这样的:
procedure MakeAllThreadsActive<T: TThreadBase>(aThreads: TThreadBaseList<T>);
或者你可以做什么乌韦·拉贝建议。任何一个将工作。
其他提示
在型
TList <TBase>
不是父类型
TList <TChild>
泛型不能使用这种方式。