It just occurred to me that I may have mis-read your question. Therefore another answer from me.
You can avoid the need to cast to a generic type (where you don't know the type parameter) at runtime by introducing a new interface that allows access to some Value
property:
Public Interface IHasValue
Public ReadOnly Property Value As Object
End Interface
Next, make sure your DataType(Of T)
class implements this interface. This means that each DataType(Of T)
object (no matter what concrete type T
is) is also an IHasValue
, and you will be able to check this with TypeOf(…) Is IHasValue
:
Public Class DataType(Of T) : Implements IHasValue
Public Value As T
Public ReadOnly Property UntypedValue As Object Implements IHasValue.Value
Get
Return Me.Value
End Get
End Property
End Class
(This duplication of Value
is necessary for two reasons: First it is necessary when DataType(Of T).Value
is a field instead of a property, and second because they do not have the same type.)
Then, where you fill your collection with fields, you can check whether a particular field is an DataType(Of T)
(and if so, unwrap the Value
from it) by doing the following:
Dim value As Object = prop.GetValue(poco)
If TypeOf(value) Is IHasValue Then ' <- is value a DataType(Of T) ? '
value = CType(value, IHasValue).Value ' <- if so, unwrap the value '
End If
Collection.Add(prop.Name, value)
This is probably more what you're after than my other answer, but let me emphasise this:
If TypeOf(…) Is … Then …
is a code smell. Perhaps you should re-think your code and investigate solutions involving polymorphism.