Можно ли назвать .NET Generics динамически? - PullRequest
0 голосов
/ 28 октября 2011

Имена сущностей были изменены, чтобы защитить их личности ...

Я создал класс с именем AnimalSearch (Of AnimalType As Animal (Of Int32))

Public Class AnimalSearch(Of AnimalType As Animal(Of Int32))

End Class

Я могу назвать этот класс так:

Dim s As New AnimalSearch(Of Monkey)()

Однако на момент звонка я не знаю, какой будет тип «Обезьяна».

Я пробовал следующую настройку, но, похоже, никуда не денется:

Public Shared Function GetAnimalSearchResults(criteria As SearchCriteria, animalType As Type) As SearchResults
    Dim s As New AnimalSearch(Of animalType)()
    ' ... (etc.)
End Function

Который я тогда вызываю из другого класса где-то так:

Dim results As SearchResults = GetAnimalSearchResults(criteria, GetType(Monkey))

В другом месте я мог бы позвонить:

Dim results As SearchResults = GetAnimalSearchResults(criteria, GetType(Giraffe))

Проблема в конструкторе (Dim s As New AnimalSearch(Of animalType)()). Его можно воспроизвести с помощью следующего, немного более простого кода:

Dim t As Type = GetType(Monkey)
Dim s As New AnimalSearch(Of t)()

Можно ли сделать то, что я пытаюсь сделать?

Ответы [ 2 ]

1 голос
/ 28 октября 2011

Вы не можете смешивать время выполнения и время компиляции, как это в .NET, но вы можете приблизиться, используя открытые универсальные типы:

Dim s As IAnimalSearch = Activator.CreateInstance (
    GetType (AnimalSearch (Of )).MakeGenericType (animalType))

Вы должны будете предоставить AnimalSearch (Of T) неуниверсальный интерфейс (я назвал его IAnimalSearch), чтобы иметь возможность манипулировать им.

1 голос
/ 28 октября 2011

Обобщения объясняются здесь: http://msdn.microsoft.com/en-us/library/w256ka79.aspx

Там в качестве преимущества говорится:

Тип Безопасность.Универсальные типы обеспечивают проверку типов во время компиляции.Типы, основанные на Object, принимают любой тип данных, и вы должны написать код, чтобы проверить, является ли входной тип данных приемлемым.С универсальными типами компилятор может перехватывать несоответствия типов до времени выполнения.

Так что я не ожидаю, что все будет работать так, как вы пытаетесь, потому что в вашем примере компиляция не знает, какой типВы не хотите создавать универсальный для (как вы читаете тип через GetType метод).

Но вместо того, чтобы создавать универсальный динамически, вы можете просто создать универсальный тип базового класса (или интерфейса).

Редактировать:

Вот как пример:

Public Sub DoSomething()

      Dim obj As New mySpecClassA
      Dim obj2 As New mySpecClassB

      Dim gen As New myGenericClass(Of myBaseClass)

      gen.DoSomething(obj)
      gen.DoSomething(obj2)
   End Sub
   Public Class myGenericClass(Of T As myBaseClass)
      Public Function DoSomething(ByVal param As T) As String
         '** Do something
         Return param.Name
      End Function
   End Class
   Public Class mySpecClassA
      Inherits myBaseClass


   End Class
   Public Class mySpecClassB
      Inherits myBaseClass


   End Class
   Public Class myBaseClass
      Public Name As String
   End Class
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...