2011-09-15 162 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)'這樣的東西。 –