Toll die Spracherweiterung für generische Typen in D2009!
Nur, bei meiner ersten Anwendung einer TList<> Ableitung
habe ich leider erste Schwierigkeiten.
Denn ich möchte eine neue TList<> Ableitung erstellen,
welche auf einer eignen Elementen-Klasse basiert, die
nur ein ID-Property enthält, um später in der neuen List-Klasse
nach dieser ID zu suchen:
Delphi-Quellcode:
TMyBase = class
strict private
fID: string;
public
constructor Create(ID: string);
property ID: string read fID;
end;
constructor TMyBase.Create(ID: string);
begin
fID := ID;
end;
In der neuen Liste möchte ich abgeleitete Klassen von TMyBase
ablegen und mit einer neuen Methode FindByID wieder finden.
Delphi-Quellcode:
TMyList<T> = class(TList<TMyBase>)
public
function FindByID(ID: string): TMyBase;
end;
function TMyList<T>.FindByID(ID: string): TMyBase;
var
c: integer;
begin
result := nil;
for c := 0 to Count - 1 do
if (Items[c] as TMyBase).ID = ID then
result := Items[c];
end;
Dies läuft so weit, nur scheint mir die nötige Typenkonvertierung
Items[c] as TMyBase fraglich.
Wenn ich jetzt eine Ableitung von TMyBase mache, sind in der
Anwendung weitere Konvertierungen nötig:
Delphi-Quellcode:
TMyName = class(TMyBase)
strict private
fName: string;
public
constructor Create(ID, aName: string);
property Name: string read fName;
end;
constructor TMyName.Create(ID, aName: string);
begin
inherited Create(ID);
fName := aName;
end;
Die Anwendung:
Delphi-Quellcode:
UseMyList := TMyList<TMyName>.Create;
UseMyList.Add(TMyName.Create('ID-1', 'Meier'));
UseMyList.Add(TMyName.Create('ID-2', 'Müller'));
UseMyList.Add(TMyName.Create('ID-3', 'Tester'));
MyString := (UseMyList.FindByID('ID-3') as TMyName).Name;
Auch hier sollte meines erachtens die Typenonvertierung
(UseMyList.FindByID('ID-3')
as TMyName)
nicht mehr nötig sein, damit das generische Konzept richtig umgesetzt wird.
Meine Vermutung ist, dass ich die FindByID Methode falsch deklariert habe,
und dass der Rückgabe-Typ hier <T> sein müsste. Leider bekomme ich mit folgender
Deklaration in D2009 neue Probleme, weil TMyBase nicht von T abgeleitet ist
(und ich auch keinen Weg fand, dies zu tun).
Delphi-Quellcode:
TMyList<T> = class(TList<TMyBase>)
public
function FindByID(ID: string): T;
end;
Bei einer echten Anwendung mit Duzenden von Ableitungen wird diese kleine
Unschönheit schnell zur grösseren Fehlerquelle. Deshalb möchte ich meinen
ersten Ansatz hinterfragen lassen.
Beiliegend die kurze Konsolen-Applikation zum Experimentieren, damit meine
Abhandlung nicht reine Theorie bleibt.
Danke für eure Lösungen.
Gruss Christoph
BTW: Refactoring von Klassennamen welche als Generische Typen verwendet werden
(hier TMyBase) scheint in D2009 (noch) nicht zu funktionieren. Gibt es einen
Workaround?