具有特定实例的通用类

时间:2011-09-15 02:55:00

标签: .net vb.net

我有一个通用类:

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)

看起来我并没有采用正确的方式,但希望我已经设法解释了我想要做的事情。

2 个答案:

答案 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)

您可以选择几种方式。它们都不比原始代码更具可读性。主要问题是您只能通过指定KV类型来引用该类。


方法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)