Problems using GetType in deserialisation

W

Will Lusted

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(Me.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
 
D

Derek Harmon

Will Lusted said:
Can anyone give me a pointer as where I'm going wrong? : :
Dim MyType As Type = Me.GetType
Return DirectCast(obj, mytype) ' fails : :
I know this should be possible, but I'm obviously missing a trick.

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
 
W

Will Lusted

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top