我已经在Delphi 2010中开始使用泛型,但是在编译这段代码时遇到了一个问题:
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));有人知道编译器为什么说这个错误吗?
发布于 2009-11-06 14:02:19
TDataProviderThread是TThreadBase的后代,但TThreadBaseList<TDataProviderThread>不是TThreadBaseList<TThreadBase>的后代。这不是继承,而是所谓的协方差,尽管从直觉上看,它似乎是相同的东西,但它不是,而且必须单独支持。目前,Delphi并不支持它,尽管希望它在将来的版本中得到支持。
协方差问题的基本原因是:如果传递给它的函数期望一个TThreadBase对象的列表,而传递给它的是一个TDataProviderThread对象的列表,那么没有什么可以阻止它调用.Add并将其他的TThreadBase对象添加到不是TDataProviderThread的列表中,现在您遇到了各种各样的丑陋问题。您需要来自编译器的特殊技巧,以确保这不会发生,否则您将失去您的类型安全。
编辑:这里有一个可能的解决方案:将MakeAllThreadsActive变成一个通用方法,如下所示:
procedure MakeAllThreadsActive<T: TThreadBase>(aThreads: TThreadBaseList<T>);或者你可以照乌韦·拉比的建议去做。两种都能用。
发布于 2009-11-06 14:01:08
类型
TList <TBase>的父类型。
TList <TChild>仿制药不能以那种方式使用。
https://stackoverflow.com/questions/1687755
复制相似问题