Problems using GetType in deserialisation

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Will Lusted

    #1

    Problems using GetType in deserialisation

    Can anyone give me a pointer as where I'm going wrong?
    I'm building a base class that persists to a database using serialization.

    GetDoc() is a base class function that reads back XML to deserialize into a
    new instance.
    The derived class needs to convert the resultant object into an instance of
    itself -
    or at least it would do except I can't get GetType to return a reference to
    the current running type to cast the object:

    Public Function GetDoc(ByVal ID As Decimal)

    Dim xs As XmlSerializer
    Dim rdr As StringReader = Me.ReadDBString (ID)
    Dim obj As Object

    Try
    xs = New XmlSerializer(M e.GetType)
    obj = xs.Deserialize( rdr)

    Dim MyType As Type = Me.GetType
    Return DirectCast(obj, mytype) ' fails
    miserable, compile error mytype not defined

    Catch ex As Exception
    ErrorLog.Add(ex )

    Finally
    xs = Nothing
    rdr = Nothing

    End Try

    End Function

    I know this should be possible, but I'm obviously missing a trick. Any
    constructive suggestions would be welcome, and thanks in advance.

    Will Lusted


  • Derek Harmon

    #2
    Re: Problems using GetType in deserialisation

    "Will Lusted" <w.lusted@_NOSP AM_btopenworld_ NOSPAM_.com> wrote in message news:WH6jd.3980 041$ic1.390947@ news.easynews.c om...[color=blue]
    > Can anyone give me a pointer as where I'm going wrong?[/color]
    : :[color=blue]
    > Dim MyType As Type = Me.GetType
    > Return DirectCast(obj, mytype) ' fails[/color]
    : :[color=blue]
    > I know this should be possible, but I'm obviously missing a trick.[/color]

    DirectCast, CType, etc., operate on the basis of an type metadata token; but
    you're giving it an instance of System.Type which is not the same.

    The following few steps will demonstrate this, instead of the above try:

    ' Dim MyType As Type = Me.GetType
    Return DirectCast( obj, GetType( MyDerivedType))

    I know this isn't what you want, because it statically binds the base class
    implementation to having knowledge of the derived class' type. This should
    compile, however, and then you can look at the MSIL in ILDASM you'll
    probably see an MSIL statement something like this:

    isinst MyDerivedType

    That's not an instance of System.Type, that's a type metadata token. It's
    pointing elsewhere within the assembly to an actual type definition (or to a
    proxy that refers to a type definition in an external, referenced assembly.)
    What this tells you is that the type is positively known at compile-time.

    Now let me rephrase your question slightly. You want to allow for an arbitrary
    derived type to be inserted into that direct cast. In fact, this derived type may
    be defined in another assembly -- that isn't even written yet, right? It's not
    going to be referenced by this version of the assembly containing the base
    class, because you don't want to re-write or re-build the base class assembly
    everytime it's derived in another new assembly.

    This sort of cast is not possible because the compiler can't identify the type
    at compile-time. You can give it a Type object, but you cannot fix-up the
    assembly's bits to know what the new derived type is.

    The solution I'd advise here is having an Overridable Protected function on the
    base class that returns an instance of the base class, and your GetDoc( ) function
    calls that to perform this typecast. Then every derived class must override
    this protected function to execute the actual typecast to itself, and hand back
    the object as an instance of the base class. The GetDoc( ) function can only
    return instances of the base class, anyway (I guess you're only doing this to
    ensure what was deserialized from the base class is also still compatible with
    the derived class ... i.e., it is structurally exactly the same?).


    Derek Harmon


    Comment

    • Will Lusted

      #3
      Re: Problems using GetType in deserialisation

      Derek,
      Thanks for your help - the 'type metadata token' went over my head a bit
      but I follow your reasoning!
      I've taken you advice and gone the overridable prot. function route, and
      that works fine.
      Many thanks for your excellent explanation and suggestion.

      Will Lusted


      "Derek Harmon" <loresayer@msn. com> wrote in message
      news:emZoJAPxEH A.392@TK2MSFTNG P12.phx.gbl...[color=blue]
      > "Will Lusted" <w.lusted@_NOSP AM_btopenworld_ NOSPAM_.com> wrote in message
      > news:WH6jd.3980 041$ic1.390947@ news.easynews.c om...[color=green]
      >> Can anyone give me a pointer as where I'm going wrong?[/color]
      > : :[color=green]
      >> Dim MyType As Type = Me.GetType
      >> Return DirectCast(obj, mytype) '
      >> fails[/color]
      > : :[color=green]
      >> I know this should be possible, but I'm obviously missing a trick.[/color]
      >
      > DirectCast, CType, etc., operate on the basis of an type metadata token;
      > but
      > you're giving it an instance of System.Type which is not the same.
      >
      > The following few steps will demonstrate this, instead of the above try:
      >
      > ' Dim MyType As Type = Me.GetType
      > Return DirectCast( obj, GetType( MyDerivedType))
      >
      > I know this isn't what you want, because it statically binds the base
      > class
      > implementation to having knowledge of the derived class' type. This
      > should
      > compile, however, and then you can look at the MSIL in ILDASM you'll
      > probably see an MSIL statement something like this:
      >
      > isinst MyDerivedType
      >
      > That's not an instance of System.Type, that's a type metadata token. It's
      > pointing elsewhere within the assembly to an actual type definition (or to
      > a
      > proxy that refers to a type definition in an external, referenced
      > assembly.)
      > What this tells you is that the type is positively known at compile-time.
      >
      > Now let me rephrase your question slightly. You want to allow for an
      > arbitrary
      > derived type to be inserted into that direct cast. In fact, this derived
      > type may
      > be defined in another assembly -- that isn't even written yet, right?
      > It's not
      > going to be referenced by this version of the assembly containing the base
      > class, because you don't want to re-write or re-build the base class
      > assembly
      > everytime it's derived in another new assembly.
      >
      > This sort of cast is not possible because the compiler can't identify the
      > type
      > at compile-time. You can give it a Type object, but you cannot fix-up the
      > assembly's bits to know what the new derived type is.
      >
      > The solution I'd advise here is having an Overridable Protected function
      > on the
      > base class that returns an instance of the base class, and your GetDoc( )
      > function
      > calls that to perform this typecast. Then every derived class must
      > override
      > this protected function to execute the actual typecast to itself, and hand
      > back
      > the object as an instance of the base class. The GetDoc( ) function can
      > only
      > return instances of the base class, anyway (I guess you're only doing this
      > to
      > ensure what was deserialized from the base class is also still compatible
      > with
      > the derived class ... i.e., it is structurally exactly the same?).
      >
      >
      > Derek Harmon
      >
      >[/color]


      Comment

      Working...