Ok, i don't think this is possible so I thought I would ask to make sure. I'm in the process of creating a function which reflects over the properties in a class and adds them to this data structure I have. Some of the properties are generic types.
So say we have DataType(Of T)
that has a .Value
property of type T
:
Dim properties = GetType(MyType).GetFields(Reflection.BindingFlags.Public Or _
Reflection.BindingFlags.Instance)
For Each prop As fieldinfo In properties
Collection.Add(prop.Name,prop.GetValue(poco))
Next
In the collection.Add
for primitive types (Integer
, String
, etc.…) I just want to add the type... but in the case of generic I want to add the DataType(Of T).Value
. I hope there is some work-around but I don't think there is a way because the type of T
can not be determined at compile time right? Ideally DirectCast(prop.getvalue(poco), DataType(Of T)).Value
would be possible. This is when you hoped even more dynamics appear than whats in .NET 4.0.
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:Next, make sure your
DataType(Of T)
class implements this interface. This means that eachDataType(Of T)
object (no matter what concrete typeT
is) is also anIHasValue
, and you will be able to check this withTypeOf(…) Is IHasValue
:(This duplication of
Value
is necessary for two reasons: First it is necessary whenDataType(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 theValue
from it) by doing the following:This is probably more what you're after than my other answer, but let me emphasise this:
First, my assumptions about what you're attempting to do:
You have some object named
poco
, having typeMyType
.MyType
has fields of different types, thus you think you need generics.You have a key-value-pair collection named
Collection
, probably having typeDictionary(Of String, Object)
?You want to transfer all of
poco
's fields (ie., their names and values) toCollection
.Second, some fundamental facts about collections and the static type system:
Untyped collections (where items are of the type
Object
) can store all sorts of values in it.Typed collections (where items are of a more specific type, e.g.
T
) can only store values having typeT
or a type derived fromT
.Third, conclusions drawn from the above:
In your case,
Collection
must be an untyped collection, if it is indeed true thatpoco
(having typeMyType
) has fields of varying types.Generics won't actually help you at all in this case, because that's not what generics are for. Generics are useful when you want to define operations (ie. methods, behaviour) that work in the same way no matter what type of object they're working on.
For example,
List(Of T)
defines a collection type that works the same no matter what typeT
is. But that does not mean that you can put anything in aList(Of T)
, because as soon as you instantiate this type — e.g. withDim xs As New List(Of String)
—,T
will be fixed to a specific type —String
—, and you end up with a typed collection that only accepts this type of values.So, again: If you need a collection that stores different kinds of objects, choose
Object
as the value type instead of trying to find a solution involving generics.That being said, there is another solution: polymorphism.
If you want your code to handle values differently, depending on their type, polymorphism is the way to go:
First, you define an interface or an abstract base class (e.g.
DataType
, though I'd strongly suggest you choose a more self-explanatory name!) that specifies what can be done with your values.Second, type
Collection
asDictionary(Of String, DataType)
. This means that only objects of typeDataType
or anything derived from it can go into the collection.Third, derive from/implement
DataType
to specify behaviour for a particular type.There is a nice slide show called Conditionals and Polymorphism that may be of interest here.