vb.net:使用泛型时调用构造函数

时间:2011-03-09 20:28:18

标签: vb.net generics

我不确定这是否可行。

我有许多实现接口IBar的不同类,并且具有带有几个值的构造函数。而不是创建一堆几乎相同的方法,是否有可能有一个通用的方法,将创建适当的构造函数?

private function GetFoo(Of T)(byval p1, byval p2) as List(Of IBar)
  dim list as new List(Of IBar)

  dim foo as T

  ' a loop here for different values of x
     foo = new T(x,p1) 
     list.Add(foo)
  ' end of loop
  return list
end function

我明白了:

'New' cannot be used on a type parameter that does not have a 'New' constraint. 

3 个答案:

答案 0 :(得分:11)

不幸的是 - .NET泛型只允许您将泛型类型约束为具有无参数构造函数,然后可以使用New T()调用...您无法指定一组特定的参数。

如果您不介意使您的类型变为可变,您可以创建一个包含带有相关参数的方法的接口,使所有类型实现接口,然后约束要实现的类型那个方法并且有一个无参数的构造函数,但它并不理想。

另一个选择是传入适当的Func xp1,每次都会返回一个新的T。这肯定很容易在C#中使用 - 而不是相当在VB IIRC中如此简单,但值得考虑。

答案 1 :(得分:4)

扩展Jon Skeet的答案,这是使用Func参数的可能解决方案:

Private Function GetFoo(Of T As IBar)(ByVal p1 As Object, ByVal p2 As Object, ctor As Func(Of Integer, Object, T)) As List(Of IBar)
    Dim list As New List(Of IBar)
    Dim foo As T
    For x = 1 To 10
        foo = ctor(x, p1)
        list.Add(foo)
    Next
    Return list
End Function

用法类似于

    GetFoo(1, 2, Function(i, o) New BarImpl(i, o))

答案 2 :(得分:2)

即使没有在通用约束中指定,也可以使用cal,构造函数。请参阅下面的示例。

    'This base class has no constructor except the default empty one
Public Class MyBaseClass

End Class

'this class inhetits MyBaseType, but it also implements a non empty constructor
Public Class MySpecializedClass
    Inherits MyBaseClass
    Public Sub New(argument As String)

    End Sub
End Class

Public Function CreateObject(Of ClassType As MyBaseClass)(argument As String) As ClassType
    'First, get the item type:
    Dim itemType As Type = GetType(ClassType)
    'Now we can use the desired constructor:
    Dim constructor As ConstructorInfo = itemType.GetConstructor(New Type() {GetType(String)})
    If constructor Is Nothing Then
        Throw New InvalidConstraintException("Constructor ""New(String)"" not found.")
    Else
        Dim result As ClassType = constructor.Invoke(New Object() {argument})
        Return result
    End If
End Function

Public Sub RunTest()
    Try
        Console.WriteLine("+----------------------------------------------------+")
        Console.WriteLine("Trying to create a instance of MyBaseClass")
        Console.WriteLine("+----------------------------------------------------+")
        Dim myobject As MyBaseClass = CreateObject(Of MyBaseClass)("string value")
        Console.WriteLine(myobject)
        Console.WriteLine("Instance of MyBaseClass created")
    Catch ex As Exception
        Console.WriteLine(ex)
    End Try
    Try
        Console.WriteLine("+----------------------------------------------------+")
        Console.WriteLine("Trying to create a instance of MySpecializedClass")
        Console.WriteLine("+----------------------------------------------------+")
        Dim myobject As MyBaseClass = CreateObject(Of MySpecializedClass)("string value")
        Console.WriteLine(myobject)
        Console.WriteLine("Instance of MySpecializedClass created")
    Catch ex As Exception
        Console.WriteLine(ex)
    End Try
End Sub