Is it possible to serialize a TCollection which is not encapsulated in a TComponent ?
For example, I have a custom TCollection. I can't use TMemoryStream.WriteComponent() on my TCollection descendant. It'll only works if I encapsulate the collection in a TComponent and then if I write this component.
Technically there is no problem but declaring a TComponent which only owns a TCollection seems a bit odd.
TMyCustomCollection = Class(TCollection) // not serializable ?
//...
End;
TMyCustomCollectionCapsule = Class(TComponent) // serializable !
Private
FMyCusColl: TMyCustomCollection;
Procedure SetMyCusColl(Const Data: TMyCustomCollection);
Published
Property CanBeSerialized: TMyCustomCollection Read FMyCusColl Write SetMyCusColl
End;
Maybe I just miss a feature of the Delphi RTL? Can a TPersistent descendent be streamed without being itself encapsulated in a TComponent ?
It only works if you put your collection in a TComponent, because TMemoryStream.WriteComponent (the name itself is a clue!) takes a TComponent as a parameter:
and TCollection is as you already discovered not a TComponent descendant. It may seem odd to have a TComponent descendant just to hold your TCollection descendant, but if you want to stream it using the WriteComponent facilities of streams, I don't see any other easy way to do it.
If you want to do this using "just" the RTL/VCL (ie not using a third party library), you would have to write a T(Memory)Stream descendant and add a WritePersistent implementation that takes an
Instance: TPersistentparameter.I haven't
delpheddelved into the TStream classes that much, but my guess is that you w/should be able to borrow a lot from the TComponent support. Certainly the class inheritance support.Having had a cursory look, it seems simple at first as
WriteComponentjust callsWriteDescendentwhich instantiates aTWriterand then calls theWriteDescendentmethod of that writer. And the TWriter already contains methods to write a collection.However, if you "just" want to stream TPersistent descendants, you will have to do a lot of work in TWriter/TReader as well as they are completely based around TComponent. And it won't be a simple case of just writing a couple of descendant. For one, they TWriter/TReader are not really set up to be derived from. For another: TStream (descendants) instantiate TWriter and TReader directly and these classes do not have virtual constructors. Which makes writing descendants for them fairly futile unless you would like to try your hand at hooking, patching the VMT and more of that interesting stuff.
All in all: the easiest way to stream your custom collection remains to "just" wrap it in a TComponent and live with the "waste" of that.