I'm wondering how I can perform serialization of a generic TObjectList<T>
container. Basically, I want to store different objects in that list, but all objects will descend from TSerializable
, which is defined as follows:
TSerializable = class abstract(TObject)
public
{ Public declarations }
procedure LoadFromStream(const S: TStream); virtual; abstract;
procedure SaveToStream(const S: TStream); virtual; abstract;
end;
Now, let's say I have these classes defined somewhere in my app:
type
TExampleClass = class(TSerializable)
private
{ Private declarations }
FIntProp: Integer;
public
{ Public declarations }
constructor Create();
procedure LoadFromStream(const S: TStream); override;
procedure SaveToStream(const S: TStream); override;
property IntProp: Integer read FIntProp write FIntProp;
end;
TAnotherExample = class(TSerializable)
private
{ Private declarations }
FStringProp: String;
public
{ Public declarations }
constructor Create();
procedure LoadFromStream(const S: TStream); override;
procedure SaveToStream(const S: TStream); override;
procedure ReverseStringProp();
property StringProp: String read FStringProp write FStringProp;
end;
I'm planning to store such objects in a list:
var
MS: TMemoryStream;
SomeList: TObjectList<TSerializable>;
begin
MS := TMemoryStream.Create();
SomeList := TObjectList<TSerializable>.Create(True);
try
SomeList.Add(TExampleClass.Create());
SomeList.Add(TAnotherClass.Create());
TExampleClass(SomeList[0]).IntProp := 1992;
TAnotherClass(SomeList[1]).StringProp := 'Some value';
// Here, a method to serialize the list...
SerializeList(SomeList, MS);
// Clear the list and reset position in the stream.
SomeList.Clear();
MS.Seek(0, soFromBeginning);
// Unserialize the list.
UnserializeList(SomeList, MS);
// Should display "Some value".
Writeln(TAnotherClass(SomeList[1]).StringProp);
finally
SomeList.Free();
MS.Free();
end;
end;
Now, how could I possibly serialize the whole list to stream and then re-create the list from that stream?
What I was thinking about was:
- Iterate through the list.
- Write each object's class name to the stream first.
- Call
SaveToStream()
on that object.
But for that approach to work, I would need to create some kind of a class register, which would be some kind of a dictionary to store known classes. It sounds like a good idea, but then I would need to call some RegisterClass()
method to add every new class to the dictionary, and I don't like that way too much.
Is there any other way, or should I just do it the way I proposed?
Thanks a bunch.