C
Codemonkey
Heya All,
Sorry, but I think it's about time for a monkey-ramble.
I've just had enough of trying to serialize even simple objects with VB. A
simple task you may think - stick the <Serialized()> attribute on the class
and away you go. As Homer would say - "D'Oh"
The root of my problem lies in the way VB implements Events and the fact
that you can't apply the <NonSerialized> attribute to the little rascals.
The result of this is that when you serialize ObjectA that has an event
EventX being handled by a method in ObjectB, ObjectB gets serialized right
along with ObjectA.
If you don't believe me, go ahead and try it. Create a serializable class
with an event and some private fields. Create a form an declare an instance
of the class and handle the event (with withevents or addhandler - doesn't
matter). Now try and serialize the instance of the class - you'll get a
serialization exception because the form (not the class you're trying to
serialize) isn't serializable!
Fair enough, you may say. This shouldn't be a big problem - just remove
event handlers before serializing. Why should I have to do this? I can't
even do it reliably (because I have no way of telling who has attached to my
events - it could be some client that I have no control over).
Another problem becomes apparent if you have a custom collection of objects
(say Trigger objects that fire an event periodically). The Collection of
triggers has it's own event which is raised when any of the triggers it
contains fires. A simple (but admittedly probably not the best) way to
implement the collection would be to use addhandler to attach to a trigger's
event when adding it to the collection. Now, guess what happens when you try
and serialize the collection - it works! WooHoo!. Now try and deserialize
it. Again "D'Oh". This time you get an exception because you can't
deserialize a delegate to a private method for security reasons!
In my travels I've had many suggestions about how to get around this and
have come up with some solutions on my own. Here are a few of them and their
pros and cons:
1) Implement ISerializable and don't serialize the events.
Pros: It Works
Cons: Too much work - have to change the GetObjectData method and
Constructor every time I add a field that is to be serialized.
2) Implement an ISerializationSurrogate to strip out the events:
Pros: Dunno
Cons: Pretty complicated to do because the Binary Formatter and Soap
Formatter don't allow you to specify surrogates, so you end up re-writing
them too.
3) Implement ISerializable in a base class and use reflection to get all
private fields in derived classes
Pros: It works
Cons: It's a hack
4) Implement the events in a C# Base class
Pros: You can specify the [NonSerialized] attribute to the event
Cons: Your logic is spread across two projects and two languages.
As you can see. I'm mighty fed up with events. I realize that the fact that
the <NonSerialized> attribute can't be applied to events is probably an
oversight and will probably be fixed in the next version. Saying that, can
anybody think of a valid reason why you would want to serialize an event
(and all objects that handle its events) anyway?
Thanks for putting up with this monkey-ramble. I'm off to learn C#
Cheers,
Trev.
Sorry, but I think it's about time for a monkey-ramble.
I've just had enough of trying to serialize even simple objects with VB. A
simple task you may think - stick the <Serialized()> attribute on the class
and away you go. As Homer would say - "D'Oh"
The root of my problem lies in the way VB implements Events and the fact
that you can't apply the <NonSerialized> attribute to the little rascals.
The result of this is that when you serialize ObjectA that has an event
EventX being handled by a method in ObjectB, ObjectB gets serialized right
along with ObjectA.
If you don't believe me, go ahead and try it. Create a serializable class
with an event and some private fields. Create a form an declare an instance
of the class and handle the event (with withevents or addhandler - doesn't
matter). Now try and serialize the instance of the class - you'll get a
serialization exception because the form (not the class you're trying to
serialize) isn't serializable!
Fair enough, you may say. This shouldn't be a big problem - just remove
event handlers before serializing. Why should I have to do this? I can't
even do it reliably (because I have no way of telling who has attached to my
events - it could be some client that I have no control over).
Another problem becomes apparent if you have a custom collection of objects
(say Trigger objects that fire an event periodically). The Collection of
triggers has it's own event which is raised when any of the triggers it
contains fires. A simple (but admittedly probably not the best) way to
implement the collection would be to use addhandler to attach to a trigger's
event when adding it to the collection. Now, guess what happens when you try
and serialize the collection - it works! WooHoo!. Now try and deserialize
it. Again "D'Oh". This time you get an exception because you can't
deserialize a delegate to a private method for security reasons!
In my travels I've had many suggestions about how to get around this and
have come up with some solutions on my own. Here are a few of them and their
pros and cons:
1) Implement ISerializable and don't serialize the events.
Pros: It Works
Cons: Too much work - have to change the GetObjectData method and
Constructor every time I add a field that is to be serialized.
2) Implement an ISerializationSurrogate to strip out the events:
Pros: Dunno
Cons: Pretty complicated to do because the Binary Formatter and Soap
Formatter don't allow you to specify surrogates, so you end up re-writing
them too.
3) Implement ISerializable in a base class and use reflection to get all
private fields in derived classes
Pros: It works
Cons: It's a hack
4) Implement the events in a C# Base class
Pros: You can specify the [NonSerialized] attribute to the event
Cons: Your logic is spread across two projects and two languages.
As you can see. I'm mighty fed up with events. I realize that the fact that
the <NonSerialized> attribute can't be applied to events is probably an
oversight and will probably be fixed in the next version. Saying that, can
anybody think of a valid reason why you would want to serialize an event
(and all objects that handle its events) anyway?
Thanks for putting up with this monkey-ramble. I'm off to learn C#
Cheers,
Trev.