VB.NET : Как обрабатывать тип переменной (параметр и возвращаемое значение)?

#.net #vb.net

#.net #vb.net

Вопрос:

Возможно ли заменить эти две функции

 Function f1 (s As String) As class1()
  Dim a() As String = Split(s)
  Dim b(UBound(a)) As class1
  For i As Integer = 0 To UBound(a)
    b(i) = New class1(a(i))
  Next
  f1 = b
End Function
  

и

 Function f2 (s As String) As class2()
  Dim a() As String = Split(s)
  Dim b(UBound(a)) As class2
  For i As Integer = 0 To UBound(a)
    b(i) = New class2(a(i))
  Next
  f2 = b
End Function
  

с помощью универсальной функции что-то вроде

 Function fGeneric (s As String,T As Type) As T()
  Dim a() As String = Split(s)
  Dim b(UBound(a)) As T
  For i As Integer = 0 To UBound(a)
    b(i) = New T(a(i))
  Next
  fGeneric = b
End Function
  

?

РЕШЕНИЕ

 Class class1
  Private _Name As String
  Public ReadOnly Property Name As String
    Get
      Name = _Name
    End Get
  End Property
  Sub New(s As String)
    _Name = s
  End Sub
End Class

Function fGeneric(Of T) (s As String) As IEnumerable(Of T)
  Dim a() As String = Split(s)
  Dim b(UBound(a)) As T
  For i As Integer = 0 To UBound(a)
    b(i) = GetType(T).InvokeMember( _
      Nothing, _
      BindingFlags.DeclaredOnly Or _
      BindingFlags.Public Or _
      BindingFlags.NonPublic Or _
      BindingFlags.Instance Or _
      BindingFlags.CreateInstance, _
      Nothing, _
      Nothing, _
      New Object(){a(i)} _
    )
  Next
  fGeneric = b
End Function
  

Response.Write(fGeneric(Of class1)("a b c")(1).Name) выводит b

Ответ №1:

 Function fGeneric(Of T) (ByVal s As String, ByVal createT As Func(Of String, T)) As IEnumerable(Of T)
  Return Split(s).Select(Function(a) createT(a))
End Function
  

назовите это следующим образом

 fGeneric(Of class1)("some, string, value", Function(a) Return New class1(a))
  

Комментарии:

1. Я получаю Type 'Func' is not defined. в первой строке.

2. @ic3b3rg Для этого вам нужен как минимум .Net 3.5. Func в противном случае находится в пространстве имен System.

3. Я изменил пул приложения на ASP.NET v4.0 , а также попытался изменить версию сервера .NET на 4.0.30319, но у меня возникли проблемы … сначала была ошибка no write access на C:WindowsMicrosoft.NETFramework64v4.0.30319Temporary ASP.NET Files , которая не существовала… Я создал и добавил разрешение, но теперь я получаю Could not load file or assembly 'System.Runtime, Version=4.0.0.0 ... . Кажется, я чего-то не понимаю — идей?

4. Хорошо, мне пришлось установить .NET 4… теперь я получаю Expression expected при вызове fGeneric

Ответ №2:

Как указывает @Joel, это может быть элегантно решено с помощью linq, но, чтобы быть ближе к вопросу @ ic3b3rg, синтаксис будет следующим:

 Function fGeneric(Of T As New) (s As String, createT As Func(Of String, T)) As T()
  Dim a() As String = Split(s)
  Dim b(UBound(a)) As T
  For i As Integer = 0 To UBound(a)
    b(i) = createT(a(i))
  Next
  fGeneric = b
End Function

fGeneric(Of class1)("some, string, value", Function(a) Return New class1(a))
  

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

При ближайшем рассмотрении я не думаю, что это сработает, поскольку мы никогда не говорили, что a T может быть сконструировано из String . Мы только сказали, что это T может быть создано с помощью new . Я не знаю, как это решить … любые предложения приветствуются (не стесняйтесь редактировать).

Комментарии:

1. Я получаю Arguments cannot be passed to a 'New' used on a type parameter. на b(i) = New T(a(i))

Ответ №3:

Взгляните на отражения. Я думаю, это может помочь вам получить результат, более близкий к вашему примеру.