Я пытаюсь создать объект определенного типа. У меня есть следующий код, но он перестал работать, потому что он не может бросить новый объект таблицы к тому, который уже определяется. Мне нужна таблица для запуска типа IEnumerable, таким образом, я не могу объявить, объект.
Public sub getTable(ByVal t as Type)
Dim table As Table(Of Object)
Dim tableType As Type = GetType(Table(Of )).MakeGenericType(t)
table = FormatterServices.GetUninitializedObject(tableType)
End sub
Так короче говоря - существует ли способ изменить тип переменной во времени выполнения? (или лучший способ сделать то, что я делаю),
Заранее спасибо.
James
Попробуйте сделать весь метод универсальным (и использовать функцию, а не подпрограмму):
Public Function GetTable(Of T)() As Table(Of T)
Взгляните на них, чтобы увидеть пару примеров того, что, как мне кажется, вы спрашиваете:
Прежде чем ответить, у меня есть два замечания:
Теперь перейдем к рассматриваемому вопросу. Вы столкнулись с отсутствием поддержки ко- (и контра-) дисперсии в .Net. Оператор присваивания никогда не будет работать, в том числе и без отражения:
' does not compile (with Option Strict On)
Dim t as Table(Of Object) = New Table(Of Product)
Причина в том, что типы на самом деле разные. Хотя Product наследуется от Object, это не означает, что Table(Of Product) не наследуется от Table(Of Object).
.Net 4 действительно имеет поддержку родовой ковариации, но только для родовых интерфейсов и типов делегатов. Аннотируя общий тип ключевым словом 'out', вы можете пометить его как общий ковариантный. Например, объявление родового интерфейса IEnumerable выглядит так:
IEnumerable(Of Out T)
Это означает, что теперь можно делать следующее:
Dim mylist As IEnumerable(Of Object) = new List<Product>()
Таким образом, можно смело присваивать список, который является IEnumerable(Of Product), переменной типа IEnumerable(Of Object).
Вот объяснение ко- и контравариантности в VB.Net
Итак, что вы можете сделать, это определить интерфейс для общей таблицы:
Interface ITable(Of Out T)
End Interface
Затем вы можете реализовать этот интерфейс в вашем общем классе Table:
Class Table(Of T)
Implements ITable(Of T)
End Class
Тогда это будет работать:
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
Конечно, еще лучше было бы использовать IEnumerable(Of T) вместо ITable(Of T), если это возможно.