Tengo un problema con mi código, que usa tipos genéricos. ¿Por qué el compilador no sabe que la lista aprobada (Result
) es TObjectList<TItem>
(TItem
es tipo para T
en TItems
)?¿Por qué no puedo pasar una TObjectList <S: T> a una función que espera una TObjectList <T>?
Interfaz:
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;
Implementación:
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;
Tienes razón, no lo miramos desde este lado. ¿Tienes alguna sugerencia de cómo refactorizar este código? Para mí es importante tener una interfaz como LoadAll y devolver la lista de resultados o pasar la lista de resultados como parámetro a TItems.LoadAll. Pero el trabajo real está haciendo por 'TItemsLoader'. TItems es solo una capa indirecta. TItems "sabe" qué tipo de artículos tendrá. TItemsLoader solo debe saber que los elementos son TItem o su descendiente. – robertw
Creo que la otra respuesta con la interfaz 'IItemsLoader' es lo que necesita hacer. Sin embargo, Rob lo ha explicado exactamente y respondió su pregunta directa. –