gpt4 book ai didi

delphi - 为什么 TGeneric 和 TGeneric 类型不兼容?

转载 作者:行者123 更新时间:2023-12-03 14:37:25 25 4
gpt4 key购买 nike

我已经开始在 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 Error] LSCore.pas(494): E2010 Incompatible types: 'TThreadBaseList(TThreadBase)' and 'TThreadBaseList(TDataProviderThread)'

虽然 TDataProviderThread 是 TThreadBase 的后代,但我不明白。

我必须通过硬类型转换来修复它:

MakeAllThreadsActive(TThreadBaseList<TThreadBase>(FProviders));

有人知道为什么编译器会出现这个错误吗?

最佳答案

TDataProviderThread 是 TThreadBase 的后代,但是 TThreadBaseList<TDataProviderThread>不是 TThreadBaseList<TThreadBase> 的后代。这不是继承,它被称为协方差,虽然直观上看起来像是同一件事,但事实并非如此,它必须单独支持。目前,Delphi 不支持它,但希望在未来的版本中会支持它。

这是协方差问题的基本原因:如果您传递给它的函数需要一个 TThreadBase 对象列表,并且您向它传递一个 TDataProviderThread 对象列表,则没有什么可以阻止它调用 .Add 并粘贴一些其他对象将 TThreadBase 对象添加到不是 TDataProviderThread 的列表中,现在您遇到了各种丑陋的问题。您需要编译器使用特殊技巧来确保这种情况不会发生,否则您将失去类型安全性。

编辑:这是一个可能的解决方案:将 MakeAllThreadsActive 设为通用方法,如下所示:

procedure MakeAllThreadsActive<T: TThreadBase>(aThreads: TThreadBaseList<T>);

或者你可以按照 Uwe Raabe 的建议去做。任何一种都可以。

关于delphi - 为什么 TGeneric<Base> 和 TGeneric<Descendant> 类型不兼容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1687755/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com