2011-09-15 163 views
0

我有一个泛型类:泛型类与特定的实例化

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是字符串的具体情况:

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) 

它看起来并不像我正在以正确的方式进行,但希望我已经设法解释我想要的这样做。

回答

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 
+0

@Enimga,更改'Protected'到'Public',滴'MyStringClass'都在一起,和你有一个近乎完美的解决方案。 Dim x As New MyClass(Of String,Integer)(StringComparer.InvariantCulture)'作品。当然,你在那里也有效。 –

+0

我几乎错过了实现IEqualityComparer(Of K)的解决方案 - 辉煌!谢谢! – ic3b3rg

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

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:静态类

您可以创建一个

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 

您与创建对象静态类(Private Sub New防止它被瞬时化)或包含Create方法的模块。这个与GenericClass具有相同的名称,但没有类型说明符。

Dim sc As StringComparer = New StringComparer() 
Dim MyObject As GenericClass(Of String, ValueType) = GenericClass.Create(Of ValueType)(sc) 

方法4:

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 

您与创建对象抛出一个异常

您可以创建,如果它的正确使用抛出异常的构造器。这里的问题是,IDE不reccognise此限制,将让构造函数无效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) 
+0

我真的很感激你已经投入到这个答案中的努力。我在想为什么我能做到这一点'昏暗myDict作为新词典(字符串,整数)(StringComparer.CurrentCultureIgnoreCase)'和'也暗淡我快译通作为新词典(整数,整数)'。换句话说,.NET Dictionary类是如何构造的,以便它可以完成我想要做的事情? – ic3b3rg

+0

编译器不知道'新(StringComparer)'将只在类被声明为'叫(字符串,V)'。它必须假定'K'类型可以是任何东西。当你创建一个'Dictionary(Of String,V)'时,它会失败,因为'String' **可能不适合'K'。你必须说服编译器''New(StringComparer)'只能在类型'K'为'String'时调用**。 –

+0

我误解了您的评论的一部分。它与Dictionary类无关。它与泛型有关。因为你有'GenericClass(Of K,V)',字典必须有相同的'(Of K,V)'。如果'K'可能**可能**不是'String',它不能允许假设Dictionary可以用String声明。编译器必须阻止你编写像'x = New GenericClass(Integer,Integer)(sc)'这样的东西。 –