Hi,
nachdem ich noch dies und jenes getestet habe, möchte ich für mich
das Thema abschließen und "Erkenntnisse" zusammenfassen.
1. Ok, mann sollte aus tlist.get die Fehlermeldung nicht rausnehmen
2. Wenn man in tlist Angst vor Fehlgriffen hat, sollte man eine Sicherheitsroutine an kritischen Stellen einrichten alà
Delphi-Quellcode:
function TMyList.ValidIndex(aindex: integer): boolean;
begin
result:= cardinal(aindex)<cardinal(Count) //cardinal <-1 ergibt immer eine Zahl größer als cardinal einer positiven Zahl
end;
3. spezifizierte Listen: Für Speicherung spezieller Datenstrukturen in Listen sind die Generics (tlist<>)bestens geeignet, der Zugriff auf die Elemente ist dann ohne "wilde" Typeumwandlungen möglich - aber
4. Will ich Vererbung sowohl der Elemente als auch der Listen realisieren
komme ich ohne Typumwandlung an irgendeiner Stelle nicht aus:
Delphi-Quellcode:
tmyobj1=class(tobject)
A:integer;
end;
tmyobj2=class(tmyobj1)
B:string;
end;
TMyList1withtmyobj1 = class(TobjectList)
function Get(Index: Integer): tMyobj1;virtual;
procedure verarbeiteA;
end;
TMyList2withmyobj2 = class(TMyList1withtmyobj1)
function Get(Index: Integer): tMyobj2;override;
procedure verarbeiteAundB;
end;
function TMyList1withtmyobj1.Get(Index: Integer): tmyobj1;
begin
result:=tmyobj1(inherited get(index));
//result:=inherited get(index); ginge auch bei direkten Naschfahren von tlist
end;
function TMyList2withtmyobj2.Get(Index: Integer): tmyobj2;
begin
result:=tmyobj2(inherited get(index));
end;
TMyList2withmyobj2 soll sowohl .verarbeiteA als auch .verarbeiteAundB können.
TMyList1withmyobj1 währe noch generisch am einfachsten, aber danach nicht mehr.
Darum füge ich eine Methode hinzu, die mir die richtigen Objecte liefert, hier überschreibe ich .get.
Ist das dann 'ne "wilde Typumwandlung"?
Der Übergang von tlist nach tobjectlist geht in der
Unit cntnrs ähnliche Wege:
Delphi-Quellcode:
function TObjectList.GetItem(Index: Integer): TObject;
begin
Result := inherited Items[Index];
end;
function TObjectList.First: TObject;
begin
Result := TObject(inherited First);
end;
//oder gar items selbst
property Items[Index: Integer]: TObject read GetItem write SetItem; default;
gerade schnell noch probiert:
property Items[Index: Integer]: TMyobj1 read GetItem write SetItem; default;
procedure SetItem(Index: Integer; AObject: tMyObj1);
function GetItem(Index: Integer): TMyObj1;
.
.
.
function TMyList1withtmyobj1.GetItem(Index: Integer): TMyObj1;
begin
Result := TMyObj1(inherited Items[Index]);
end;
procedure TMyList1withtmyobj1.SetItem(Index: Integer; AObject: TMyObj1);
begin
inherited Items[Index] := AObject;
end;
so braucht man .get nicht zu definieren und kann wie gwohnt auf items zugreifen
Danke allen Diskutanten
Grüße Uwe