Hidden Gems in VB2010 – Serializing Objects that Raise Events (Jonathan Aneja)
By now you’ve likely heard about the major new features coming in VB 2010, but there’s also a number of smaller additions in the language and IDE that might not be as readily noticeable. “Hidden Gems” will be a multi-part series where we’ll explore some of these smaller enhancements. First up – serialization!
Let’s say you have a simple entity class that you need to serialize and send over the wire. This class implements INotifyPropertyChanged which contains an event. When attempting to serialize an instance of this class, if the delegate which backs the event has its Target property referencing an Object which is not serializable, then the entity class itself can no longer be serialized. For example, if a Form was handling the event raised from this class, the class can no longer be serialized.
In C# the solution is simple – just use a field attribute target to tell the serializer not to attempt to serialize the delegate and any objects it references:
public event PropertyChangedEventHandler PropertyChanged;
VB doesn’t support attribute targets for fields though, so the way to work around this is to use a custom event:
Public Class Customer
Private _PropertyChanged As PropertyChangedEventHandler
Public Custom Event PropertyChanged As PropertyChangedEventHandler _
AddHandler(ByVal value As PropertyChangedEventHandler)
_PropertyChanged = CType([Delegate].Combine(_PropertyChanged,
RemoveHandler(ByVal value As PropertyChangedEventHandler)
_PropertyChanged = CType([Delegate].Remove(_PropertyChanged,
RaiseEvent(ByVal sender As Object, ByVal e As PropertyChangedEventArgs)
If _PropertyChanged IsNot Nothing Then
(For a more thorough implementation see Rocky’s excellent blog entry). That’s a lot of code to write though – basically you’re having to take control of the backing field yourself just to apply the attribute manually.
How does VB2010 help?
We now allow the NonSerialized attribute to be placed on an Event. The compiler will then:
1. Suppress the error that says “this attribute cannot be used on this type of declaration”
2. Apply the NonSerialized attribute to the event’s backing field.
As a result you’ll be able to type the following in VB 2010 (try it, it works in Beta2!):
Event PropertyChanged As PropertyChangedEventHandler