2016-02-26 24 views
0

下面的代碼是用Vb.Net編寫的,但我也接受C#解決方案。如何編寫智能泛型集合索引器?


我有這些類:

  • CommandlineParameter(OF T)

    Class CommandlineParameter(Of T) 
    End Class 
    
  • CommandlineParameter

    Class CommandlineParameter : Inherits CommandlineParameter(Of Object) 
    End Class 
    
  • CommandlineParameterCollection

    Class CommandlineParameterCollection : Inherits Collection(Of CommandlineParameter) 
    End Class 
    

CommandlineParameterCollection我添加了一個通用Add方法:

Public Shadows Sub Add(Of T)(ByVal param As CommandlineParameter(Of T)) 

    If Me.Contains(param.Name) OrElse Me.Contains(param.ShortName) Then 
     Throw New ArgumentException(message:="Parameter already exists.", "param") 

    Else 
     MyBase.Add(param) 

    End If 

End Sub 

然後,我用它這樣:

Dim cmds As New CommandlineParameterCollection 
With cmds 
    .Add(Of String)(Param1) ' CommandlineParameter(Of String) 
    .Add(Of Boolean)(Param2) ' CommandlineParameter(Of Boolean) 
End With 

現在的問題是,當我調用索引器,它返回給我一個CommandlineParameterCommandlineParameter(Of Object)),那麼我需要指定直接加法在我的源代碼施放指定它是什麼類型,一個例子:

Console.WriteLine(CStr(cmds(Param1).Value)) 
Console.WriteLine(Cbool(cmds(Param2).Value)) 

然後避免這種情況,我想指定一個泛型類型索引,但我發現,.NET不支持此功能。

因此,通過目前,我有這個索引:

Default Public Overloads Property Item(ByVal paramName As String) As CommandlineParameter 
    <DebuggerStepThrough> 
    Get 
     Return Me.Find(paramName) 
    End Get 
    <DebuggerStepThrough> 
    Set(ByVal value As CommandlineParameter) 
     Me(Me.IndexOf(paramName)) = value 
    End Set 
End Property 

這個存在什麼解決方案,以避免額外的鑄件,並返回我想要的那種類型的值?

我會澄清CommandlineParameterCommandlineParameter(Of Object))類是根本沒有必要的,如果解決方案意味着刪除它,那麼我可以刪除它,因爲我設計它只是爲了更友好的使用該對象。

+0

外接應該只是添加泛型類型。而不是'.Add(Of String)(Param1)'它應該是'.Add(Of T)(Param1)' –

回答

1

由於Collection<T>假設,每一個項目都有相同的T,你不能存儲CommandlineParameter<string>CommandlineParameter<bool>在同一Collection<T>

IMO,最好的,你可以在這裏做是模仿收集行爲是這樣的:

class CommandLineParameter<T> { } 
class CommandlineParameterCollection 
{ 
    // use most common type to store items in inner collection - object 
    private readonly List<object> inner; 

    public void Add<T>(CommandLineParameter<T> value) 
    { 
     inner.Add(value); 
    } 

    public void Remove<T>(CommandLineParameter<T> value) 
    { 
     inner.Remove(value); 
    } 

    public CommandLineParameter<T> GetAt<T>(int index) 
    { 
     // will throw InvalidCastException if T at given index doesn't match passed T 
     return (CommandLineParameter<T>)inner[index]; 
    } 
} 
+0

我的意思是模仿整個收藏行爲 - 'Add '和'Remove '每次你給他們打電話時都會傳遞不同的'T' - 但不會繼承'Collection '。你說得對 - 'GetAt'是一個索引器替代品。 – Dennis