2

I have one class implementing ISerializable interface, with one private field that is saved and retrieved:

Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
    _name= info.GetString("_name")
End Sub

Now, I want to add a new private field, but since it did not exist previously, when I try to open a serialized object I get an exception when trying to get this field, in the custom deserialization constructor. The solution I've come up with is to use a Try...Catch block, as follows:

Protected Sub New(ByVal info As SerializationInfo, _
                 ByVal context As StreamingContext)
    _name= info.GetString("_name")
    Try
       _active= info.GetBoolean("_active")
    Catch ex As Exception
        _active= False
    End Try
End Sub

It works, but it seems a bit messy to me, moreover because I will have to add a new Try...Catch block for each new field I want to add. Is there any better way of doing this?

Thanks!

EDIT: In this answer t0mm13b says that "There is a more neater way to do this in 2.0+ upwards". Any ideas about what is he talking about?

Community
  • 1
  • 1
Tao Gómez Gil
  • 2,228
  • 20
  • 36

1 Answers1

1

There is no built-in method that allows you to first determine if a particular value exists (e.g. Exists). There is also no Get... method which simply returns Nothing if the value does not exist (e.g. TryGet). However, the one way that you can do it which avoids the potential for exceptions is to use a For Each loop to iterate through all of the values in the SerializationInfo collection. For instance:

For Each i As SerializationEntry In info
    Select Case i.Name
        Case "_name"
            _name = DirectCast(i.Value, String)

        ' ...
    End Select
Next

Note: It may be surprising to you that you can use a For Each loop on a SerializationInfo object, since it does not implement the IEnumerable interface (nor the generic equivalent). However, For Each in VB.NET actually works with any object that has a public GetEnumerator method. So, even though it leads to some confusion, objects don't technically need to implement IEnumerable in order for you to iterate through them with a For Each loop. Since the SerializationInfo class does expose a public GetEnumerator method, you can iterate through it with a For Each loop.

Steven Doggart
  • 43,358
  • 8
  • 68
  • 105