So nach dem Motto würde ich das machen, ungetestet:
Delphi-Quellcode:
TMyList = class
private
var
FList: TList<IListData>;
public
function Get<T: IInterface>(const AIndex: Integer): T;
end;
...
function TMyList.Get<T>(const AIndex: Integer): T;
begin
if not Supports(FList[AIndex], Result) then
Result := nil;
Ich fürchte mein Verständnis für Interfaces und Generics reicht nicht aus um das Beispiel nachzuvollziehen... IListData als Typ der Liste hätte ich noch als Tippfehler gesehen sodass daraus FList:TList<TListData>; wird?
Die Get-Funktion wird dann zu:
Delphi-Quellcode:
function TMyList.Get<T>(const AIndex: Integer): T;
begin
if not Supports(FList[AIndex].fMy, Result) then //<- Error
Result := nil;
end;
wobei das Resultat auf IInterface-Support eingeschränkt wird(?). Da man aber Supports nicht ohne eine IID_xxx aufzurufen kann, muss man hier wieder ein konkretes Interface angeben. Also etwa:
Delphi-Quellcode:
function TMyList.Get<T>(const AIndex: Integer): T;
begin
if not Supports(FList[AIndex].fMy, IID_BASE, Result) then
Result := nil;
end;
Womit eigentlich nur mehr das IBase-Interface von der Funktion zu haben wäre? Ausprobieren konnte ich das ganze nicht, denn obwohl sich der Code der Liste compilieren lässt, bekomme ich dann bei einem Zugriffsversuch vom Compiler die Meldung: "E2531 Methode 'Get' erfordert explizite Typargumente", was eventuell daran liegt, dass ich keinen korrekten Aufruf hinbekommen habe..
Code:
i: IBase;
i := fMyList.Get(0);
i := fMyList.Get(0) As IBase;
...
Wünschen würde ich mir ja eher sowas wie:
Delphi-Quellcode:
Var
iSom: ISomeThing;
iInt: IInteger;
begin
for i := 0 To fMyList.Count-1 Do
begin
if fMyList.Get(i, iInt) Then
iInt.SetValue(Random(100));
if fMyList.Get(0, iSom) Then
iSom.DoSomething;
..
Unabhängig von der korrekten Implementierung frage ich mich auch noch wie die Performanz hier aussieht. Es werden ja ständig Interfaces über Strings gesucht?