Это работает, только если вы поместите свою коллекцию в TComponent, потому что TMemoryStream.WriteComponent (само имя является подсказкой!) Принимает TComponent в качестве параметра:
procedure WriteComponent(Instance: TComponent);
и TCollection, как вы уже обнаружили, не является потомком TComponent. Может показаться странным, что потомок TComponent просто содержит вашего потомка TCollection, но если вы хотите передать его с помощью потоковых средств WriteComponent, я не вижу другого простого способа сделать это.
Если вы хотите сделать это, используя «просто» RTL / VCL (т.е. не используя стороннюю библиотеку), вам придется написать потомок T (Memory) Stream и добавить реализацию WritePersistent, которая принимает Instance: TPersistent
параметр.
Я не delphed так много углублялся в классы TStream, но я предполагаю, что у вас будет много возможностей позаимствовать у поддержки TComponent. Конечно, поддержка наследования классов.
При поверхностном взгляде на первый взгляд кажется простым, что WriteComponent
просто вызывает WriteDescendent
, который создает экземпляр TWriter
, а затем вызывает метод WriteDescendent
этого писателя. И TWriter уже содержит методы для написания коллекции.
Однако, если вы «просто» хотите транслировать потомков TPersistent, вам придется проделать большую работу в TWriter / TReader, так как они полностью основаны на TComponent. И это не будет простым случаем просто написать пару потомков. С одной стороны, они TWriter / TReader на самом деле не настроены для получения. Для другого: TStream (потомки) создают экземпляры TWriter и TReader напрямую, и у этих классов нет виртуальных конструкторов. Что делает написание потомков для них довольно бесполезным, если вы не хотите попробовать свои силы в подключении, исправлении VMT и других интересных вещах.
В общем и целом: самый простой способ потоковой передачи вашей пользовательской коллекции - просто "обернуть" ее в компонент TComon и жить с "ненужными" последствиями.