rob*_*rtw 8 delphi generics tobjectlist
我的代码有问题,它使用泛型类型.为什么编译器不知道传递的list(Result
)是一个TObjectList<TItem>
(TItem
是T
in的类型TItems
)?
接口:
type
TItem = class
end;
type
IItemsLoader = interface
procedure LoadAll(AList : TObjectList<TItem>);
end;
type
TItemsLoader = class(TInterfacedObject, IItemsLoader)
public
procedure LoadAll(AList : TObjectList<TItem>);
end;
type
IItems<T : TItem> = interface
function LoadAll : TObjectList<T>;
end;
type
TItems<T : TItem> = class(TInterfacedObject, IItems<T>)
private
FItemsLoader : TItemsLoader;
public
constructor Create;
destructor Destroy; override;
function LoadAll : TObjectList<T>;
end;
Run Code Online (Sandbox Code Playgroud)
执行:
procedure TItemsLoader.LoadAll(AList: TObjectList<TItem>);
begin
/// some stuff with AList
end;
{ TItems<T> }
constructor TItems<T>.Create;
begin
FItemsLoader := TItemsLoader.Create;
end;
destructor TItems<T>.Destroy;
begin
FItemsLoader.Free;
inherited;
end;
function TItems<T>.LoadAll: TObjectList<T>;
begin
Result := TObjectList<T>.Create();
/// Error here
/// FItemsLoader.LoadAll(Result);
end;
Run Code Online (Sandbox Code Playgroud)
在出现错误的函数中,Result
is a TObjectList<T>
,其中T
是 的某个子类TItem
,但编译器不知道它具体是什么类。编译器必须对其进行编译,以便可以安全地运行任何T
. 这可能与 的参数类型不兼容LoadAll
,后者需要 a TObjectList<TItem>
,因此编译器会拒绝该代码。
假设T
是TItemDescendant
,编译器允许错误代码编译并执行。如果LoadAll
调用AList.Add(TItem.Create)
,那么AList
最终会持有不是 a 的东西TItemDescendant
,即使它是 a TObjectList<TItemDescendant>
。它持有的对象的类型不同于其泛型类型参数所表示的类型。
仅仅因为S
是 的子类型T
并不意味着它X<S>
是 的子类型X<T>
。