Hallo
Ich habe in meinem code viele Objekte und Objektlisten, die sich selbst in einen stream speichern und laden können und wie folgt aufgebaut sind
Delphi-Quellcode:
//Liste
procedure TObjektListe.LoadFromStream(Stream: TStream);
Var Version:integer;
i,len:integer;
Eintrag: TListeneintrag;
begin
clear;
with TReader.create(Stream,FileStreamBuffer) do
try
//Version auslesen
Version:=ReadInteger;
len:=readinteger;
… weitere Eigenschaften aus stream laden
finally
free;
end;
//einträge auslesen
for i:=0 to len-1 do
begin
Eintrag:= TListeneintrag.Create;
Eintrag.LoadFromStream(stream);
add(Eintrag);
end;
end;
//Eintrag:
procedure TListeneintrag.LoadFromStream(Stream: TStream);
var Version:integer;
begin
with TReader.create(Stream,FileStreamBuffer) do
try
//Version auslesen
Version:=ReadInteger;
Eigenschaft1 := ReadString;
Eigenschaft2 := ReadString;
…
If Version>Version43 then
EigenschaftXYZ := ReadString;
finally
free;
end;
end;
Savetostream der beiden entsprechend. Die Version dient mir zum flexiblen Erweitern der Datei um neue Eigenschaften.
Ich möchte gern diesen code, dessen Rumpfbereich in allen Objekten und ObjektListen vorkommt gern verallgemeinern, da der code sich ständig wiederholt und ich teilweise einen Haufen Warnungen wegen der Nichtbenutzung der Version erhalte (nicht jedes Objekt ändert sich ständig im Dateiaufbau).
Ich hätte gern ein Basisobjekt, das wie folgt aussieht:
Delphi-Quellcode:
TBasisListenEintrag=class…
Private
Procedure LoadfromStream…
Procedure Savetostream…
Public
Procedure SaveData… //soll die abgeleitete Klasse
Procedure Loaddata… //erst implementieren
….
procedure TBasisListenEintrag.LoadFromStream(Stream: TStream);
var DateiVersion:integer;
begin
with TReader.create(Stream,FileStreamBuffer) do
try
//Version auslesen
Dateiversion:=ReadInteger;
LoadData(Reader,Dateiversion)
finally
free;
end;
end;
//abgeleitetes Objekt:
procedure TAbgeleiteterListenEintrag.LoadData(Reader:Treader;const Dateiversion:integer);
begin
with reader do
begin
Eigenschaft1 := ReadString;
Eigenschaft2 := ReadString;
…
If DateiVersion>Version43 then
EigenschaftXYZ := ReadString;
end;
end;
Das abgeleitete Objekt soll nur die Daten lesen und schreiben, der Reader/Writer soll im Basisobjekt bei load/savetostream erstellt werden, das abgeleitete Objekt soll davon nichts mitbekommen.
Für das Objekt ist das auch kein Problem, scheitern tue ich an der Objektliste
Delphi-Quellcode:
procedure TBasisObjektList.LoadFromStream(Stream: TStream);
Var Version:integer;
i,len:integer;
Eintrag: T????;
begin
clear;
with TReader.create(Stream,FileStreamBuffer) do
try
//Version auslesen
Version:=ReadInteger;
len:=readinteger;
//weitere Eigenschaften aus stream laden
Loaddata(…)
finally
free;
end;
//einträge auslesen
for i:=0 to len-1 do
begin
Eintrag:= T????.Create;
Eintrag.LoadFromStream(stream);
add(Eintrag);
end;
end;
Bei Eintrag:= T????.Create; müsste ich wissen, welche abgeleitete Klasse die Objektliste verwaltet. Wenn ich Eintrag als TBasisobjekt angebe, rufe zwar loadfromstream auf, aber an das eigentliche auslesen der Daten per loaddata komm ich nicht ran.
Geht das überhaupt? Kann ich die Objektliste z.B. so flexibel gestalten das man z.B. beim create der objektliste den Typ der Einträge mit übergeben kann, oder gibt es eine andere Lösungsmöglichkeit?
Danke im Voraus Frank