Hidden Gems in VB2010 – Serializing Objects that Raise Events (Jonathan Aneja)

Hidden Gems in VB2010 – Serializing Objects that Raise Events (Jonathan Aneja)

  • Comments 3

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:

    [field: NonSerialized]

    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:

 

<Serializable()>

Public Class Customer

    Implements INotifyPropertyChanged

 

    <NonSerialized()>

    Private _PropertyChanged As PropertyChangedEventHandler

 

    Public Custom Event PropertyChanged As PropertyChangedEventHandler _

        Implements INotifyPropertyChanged.PropertyChanged

 

        AddHandler(ByVal value As PropertyChangedEventHandler)

            _PropertyChanged = CType([Delegate].Combine(_PropertyChanged,

                                     value), PropertyChangedEventHandler)

        End AddHandler

 

        RemoveHandler(ByVal value As PropertyChangedEventHandler)

            _PropertyChanged = CType([Delegate].Remove(_PropertyChanged,

                                     value), PropertyChangedEventHandler)

        End RemoveHandler

 

      RaiseEvent(ByVal sender As Object, ByVal e As PropertyChangedEventArgs)

          If _PropertyChanged IsNot Nothing Then       

              _PropertyChanged.Invoke(sender, e)

          End If

      End RaiseEvent

    End Event

 

    ...

End Class

 

(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!):

 

    <NonSerialized()>

    Event PropertyChanged As PropertyChangedEventHandler

Leave a Comment
  • Please add 1 and 1 and type the answer here:
  • Post
  • >VB doesn’t support attribute targets for fields though, so the way to work around this is to use a custom event:

    Isn't the right way just to fix the language?

  • Yes! We should fix the language -- by supporting more attribute targets than we do currently. We have this on our list of "features we want to consider for future versions of the language".

    --

    Lucian Wischik, VB spec lead

  • below the value of the information you provide will help me a lot of work in the final thanks

Page 1 of 1 (3 items)