Ho un problema con il mio codice, che utilizza tipi generici. Perché il compilatore non sa che l'elenco passato (Result
) è un TObjectList<TItem>
(TItem
è il tipo per T
in TItems
)?Perché non posso passare una TObjectList <S: T> a una funzione che si aspetta una TObjectList <T>?
Interfaccia:
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;
Implementazione:
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;
Hai ragione, non ho guardato la cosa da questo lato. Hai qualche suggerimento su come refactoring questo codice? Per me è importante avere un'interfaccia come LoadAll e restituire l'elenco dei risultati o passare l'elenco dei risultati come parametro per TItems.LoadAll, ma il lavoro vero è fatto da 'TItemsLoader'. TItem è solo un livello indiretto. I TIEM "sanno" che tipo di articoli avranno. TItemsLoader dovrebbe sapere solo che gli elementi sono TItem o il suo discendente. – robertw
Credo che l'altra risposta con l'interfaccia 'IItemsLoader', è ciò che è necessario modificare. Tuttavia, Rob l'ha spiegato esattamente e ha risposto alla tua domanda diretta. –