views:

90

answers:

1

Given an extension method like this:

Public Sub RehydrateTo(Of T As New)(ByVal input As String, ByRef output As T)

   Dim ms As MemoryStream = MsFromString(input)
   Dim f As New DataContractSerializer(GetType(T))

   Try
      output = CType(f.ReadObject(ms), T)
   Catch ex As SerializationException
      output = New T
      Dim ild As ILegacyDeserializer = TryCast(output, ILegacyDeserializer)
      If Not ild Is Nothing Then
         ' ... you get the idea
      End If
   End Try

End Sub

and a type MyCollection that inherits from ObservableCollection(Of V), we find that calling someString.RehydrateTo(instanceOfMyCollection) can fail in the exception handler. The problem is that GetType(T) does not always evaluate to "MyCollection" -- while in the exception handler, it evaluates to "__Canon".

( System.__Canon being some kind of CLR magic that means a canonical instantiation of a generic )

How can we work around this?

+1  A: 

The strange behavior of T is only in the exception handler, so you can just move the code out of the handler, like this:

Dim exceptionCaught As Boolean
Try
   output = CType(f.ReadObject(ms), T)
Catch ex As SerializationException
   exceptionCaught = True
End Try

If Not exceptionCaught Then
   Exit Sub
End If

'here we put the code that we want to handle the exception

The problem is that the exception handler is "code shared" across multiple types. when we're in the exception handler, we aren't in code specific to any class we wrote, we're in the canonical instantiation of a generic -- this is why T = System.__Canon.

The workaround is just to not evaluate T while in a code-shared block.

Jeff Paulsen