我有一个通用类:
Public Class MyClass(Of K,V)
Private _Dictionary As Dictionary(Of K,V)
Sub New
_Dictionary = New Dictionary(Of K,V)
End Sub
End Class
我想在K为String的特定情况下重载New:
Sub New(sc As StringComparer)
_Dictionary = New Dictionary(Of String,V)(sc)
End Sub
这会导致错误:
Dictionary(Of String, V) cannot be converted to Dictionary(Of K, V)
看起来我并没有采用正确的方式,但希望我已经设法解释了我想要做的事情。
答案 0 :(得分:3)
你需要做这样的事情:
Public Class [MyClass](Of K,V)
Private _Dictionary As Dictionary(Of K,V)
Public Sub New()
_Dictionary = New Dictionary(Of K, V)
End Sub
Public Sub New(comparer As IEqualityComparer(Of K))
_Dictionary = New Dictionary(Of K, V)(comparer)
End Sub
End Class
'This class now optional as per comment
Public Class MyStringClass(Of V)
Inherits [MyClass](Of String, V)
Public Sub New(sc As StringComparer)
MyBase.New(sc)
End Sub
End Class
答案 1 :(得分:2)
应用程序运行时,动态创建通用类型。当您引用GenericClass(Of String, Integer)
时,它会将类的自定义版本加载到内存中。当您稍后引用GenericClass(Of String, Long)
时,它会将另一个单独的自定义类加载到内存中。在加载类之前,您无法访问任何成员,包括构造函数。在调用其中一个构造函数之前,您必须始终参考GenericClass(Of String, V)
。
您可以选择几种方式。它们都不比原始代码更具可读性。主要问题是您只能通过指定K
和V
类型来引用该类。
方法1:静态方法
使用共享/静态Create
方法创建对象。
Public Class GenericClass(Of K, V)
Private _Dictionary As Dictionary(Of K, V)
Sub New()
_Dictionary = New Dictionary(Of K, V)
End Sub
Public Shared Function Create(sc As StringComparer) As GenericClass(Of String, V)
Dim NewObject As New GenericClass(Of String, V)
' TODO: Initialise object.
Return NewObject
End Function
End Class
使用以下命令创建对象:
Dim sc As StringComparer = New StringComparer()
Dim MyObject As GenericClass(Of String, ValueType) = GenericClass(Of String, ValueType).Create(sc)
方法2:继承类
创建一个继承的类,将K
类型强制为String
。
Public Class NotSoGenericClass(Of V)
Inherits GenericClass(Of String, V)
Public Sub New(sc As StringComparer)
MyBase.New()
' TODO: Initialise object.
End Sub
End Class
使用以下命令创建对象:
Dim sc As StringComparer = New StringComparer()
Dim MyObject As New NotSoGenericClass(Of ValueType)(sc)
或
Dim sc As StringComparer = New StringComparer()
Dim MyObject As GenericClass(Of String, ValueType) = New NotSoGenericClass(Of ValueType)(sc)
方法3:静态类
您可以创建静态类(Private Sub New
阻止其即时化)或包含Create
方法的模块。这个名称与GenericClass相同,但没有类型说明符。
Public Class GenericClass
Private Sub New()
End Sub
Public Shared Function Create(Of V)(sc As StringComparer) As GenericClass(Of String, V)
Dim NewObject As New GenericClass(Of String, V)
' TODO: Initialise object.
Return NewObject
End Function
End Class
使用以下命令创建对象:
Dim sc As StringComparer = New StringComparer()
Dim MyObject As GenericClass(Of String, ValueType) = GenericClass.Create(Of ValueType)(sc)
方法4:抛出异常
如果使用不正确,您可以创建一个抛出异常的构造函数。这样做的问题是IDE不会重新识别此限制,并且会在无效的K
类型上调用构造函数。
Sub New(sc As StringComparer)
If GetType(K) IsNot GetType(String) Then Throw New InvalidCastException("Type K must be String for this constructor.")
_Dictionary = New Dictionary(Of K, V)
End Sub
使用以下命令创建对象:
Dim sc As StringComparer = New StringComparer()
Dim MyObject As New GenericClass(Of String, ValueType)(sc)
但这引发了一个例外:
Dim sc As StringComparer = New StringComparer()
Dim MyObject As New GenericClass(Of Object, ValueType)(sc)