Before answering, I do have two remarks:
- I agree with Joel that a generic solution would be much simpler, but without more context I'll assume you really do need reflection
- why do you use FormatterServices.GetUninitializedObject()? This will not call the constructor of your Table object. I'm guessing you actually mean to use Activator.CreateInstance() here.
Now, over to the issue at hand. You have run into the lack of support for co- (and contra-)variance in .Net. The assignment statement will never work, also without reflection:
' does not compile (with Option Strict On)
Dim t as Table(Of Object) = New Table(Of Product)
The reason is that the types are actually different. Although Product inherits from Object, that does not imply that Table(Of Product) does not inherit from Table(Of Object).
.Net 4 actually does have support for generic covariance, but only for generic interfaces and delegate types. By annotating a generic type with the 'out' keyword, you can mark it as generically covariant. For example, the IEnumerable generic interface declaration looks like this:
IEnumerable(Of Out T)
This means that it's now possible to do the following:
Dim mylist As IEnumerable(Of Object) = new List<Product>()
So one can safely assign a list which is IEnumerable(Of Product) to a variable of type IEnumerable(Of Object).
Here's an explanation of co- and contravariance in VB.Net
So, what you could do is define an interface for the generic table:
Interface ITable(Of Out T)
End Interface
Then you can implement this interface in your generic Table class:
Class Table(Of T)
Implements ITable(Of T)
End Class
Then this will work:
Function CreateTable(ByVal t As Type) As ITable(Of Object)
Dim result As ITable(Of Object)
Dim type = GetType(Table(Of )).MakeGenericType(t)
result = FormatterServices.GetUninitializedObject(type)
Return result
End Function
Of course, even better would be to use IEnumerable(Of T) instead of ITable(Of T), if possible.