Aggiornamento
La domanda originale aveva un problema che ho individuato (vedi sotto). Tuttavia, la correzione che descrivo è valida per XE3 e versioni successive, ma il programma riportato di seguito non viene compilato in XE2. Quindi concludo che questo è un bug del compilatore generico XE2.
In ogni caso, ecco una soluzione per Delphi XE2:
{$APPTYPE CONSOLE}
type
IStorageObject = interface(IInterface)
end;
TObjectStorage<T: IStorageObject> = class(TObject)
end;
IKeyStorageObject<TKey> = interface(IStorageObject)
end;
TKeyObjectStorage<TKey; T: IKeyStorageObject<TKey>, IStorageObject> = class(TObjectStorage<T>)
end;
TImplementingClass<TKey> = class(TInterfacedObject, IStorageObject, IKeyStorageObject<TKey>)
end;
begin
TKeyObjectStorage<Integer, TImplementingClass<Integer>>.Create;
end.
risposta originale
Sarebbe stato meglio se si fosse previsto un programma completo che espone l'errore del compilatore . È necessario tentare di creare un'istanza di un oggetto per vedere quell'errore.
Ma, penso di aver riprodotto il tuo problema. Quindi credo che il problema è che questo codice:
TKeyObjectStorage<TKey, T: IKeyStorageObject<TKey>> = ...
vale il vincolo generico sia TKey
e T
. Ora, chiaramente desideri solo il vincolo da applicare al T
quindi è necessario scrivere:
TKeyObjectStorage<TKey; T: IKeyStorageObject<TKey>> = ...
Ecco un breve programma che compila in seguito alla modifica Delphi XE3:
{$APPTYPE CONSOLE}
type
IStorageObject = interface(IInterface)
end;
TObjectStorage<T: IStorageObject> = class(TObject)
end;
IKeyStorageObject<TKey> = interface(IStorageObject)
end;
TKeyObjectStorage<TKey; T: IKeyStorageObject<TKey>> = class(TObjectStorage<T>)
end;
TImplementingClass<TKey> = class(TInterfacedObject, IKeyStorageObject<TKey>)
end;
begin
TKeyObjectStorage<Integer, TImplementingClass<Integer>>.Create;
end.
Questo è piuttosto una sfumatura, il cambio di una virgola in un punto e virgola. Programmare con una punteggiatura significativa non è mai molto divertente. Detto questo, hai familiarità con la differenza tra virgole e punti e virgola in liste parametriche formali e quindi non dovrebbe essere troppo sorprendente vedere la stessa distinzione tracciata qui.
Il documentation fa coprire questo si badi bene:
Multiple Type Parameters
When you specify constraints, you separate multiple type parameters by semicolons, as you do with a parameter list declaration:
type
TFoo<T: ISerializable; V: IComparable>
Like parameter declarations, multiple type parameters can be grouped together in a comma list to bind to the same constraints:
type
TFoo<S, U: ISerializable> ...
In the example above, S
and U
are both bound to the ISerializable
constraint.
Hai appena cambiare completamente la questione !!? Hai appena sostituito quella virgola con il punto e virgola? !! E il codice che hai postato non è ancora abbastanza per mostrare l'errore.Per favore, fai ciò che ho suggerito e pubblica un ** programma completo **. Ti ho mostrato come nella mia risposta. –
Ci scusiamo per questo David, Sì, ma il ',' non ha generato un errore o questo errore ed è stato solo un leggero svista. Sry di nuovo. – Hugie
@Hugie, non cambiare la domanda per deviare dal suo problema originale. Eventuali errori presenti nell'originale devono rimanere nella domanda; tuttavia creare un'app console con il codice minimo per dimostrare il problema. e incolla ** quell'app console nella domanda. – Johan