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?
The strange behavior of T is only in the exception handler, so you can just move the code out of the handler, like this:
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.