2011-08-02 41 views
1

我想使用一個變量,它只是一個字符串列表的列表。 我如下聲明它:是否可以使用IList(Of IList(Of String))?

Dim iRows As New List(Of List(Of String)) 

然後我試圖把它作爲參數傳遞給另一個方法,我已經定義如下方法:

Public Sub Import(ByVal Rows As IList(Of IList(Of String))) 
    For Each Row As IList(Of String) In Rows 
     ImportRow(Row) 
    Next 
End Sub 

不幸的是,當我嘗試運行該代碼,當它試圖將我的變量傳遞給我的方法時,出現以下錯誤。

System.InvalidCastException了未處理由用戶代碼 消息=「無法轉換類型的對象 'System.Collections.Generic.List 1[System.Collections.Generic.List 1 [System.String]]' 爲類型「System.Collections.Generic.IList 1[System.Collections.Generic.IList 1 [System.String]]」「。

當我改變方法定義使用類型而不是接口如下,它的工作原理。

Public Sub Import(ByVal Rows As List(Of List(Of String))) 
    For Each Row As IList(Of String) In Rows 
     ImportRow(Row) 
    Next 
End Sub 

那麼,以這種方式使用泛型與接口是不可能的嗎?只要我沒有嵌套它們,它就可以正常工作。

回答

5

是的,這是可能創建一個IList(Of IList(Of String)) - 但List(Of (List(Of String))之一。想想看,在後一種情況下,你可以調用

listOfLists.Add(arrayOfStrings) 

爲一個字符串數組實現IList(Of String)

基本上這與考慮IList(Of Fruit)List(Of Banana)完全一樣 - 一串香蕉不是水果碗,因爲你不能添加一個蘋果。

對於您的情況,您需要創建List(Of IList(Of String))而不是 - 聲明IList(Of List(Of String))

現在有趣的是,你可以使用一個List(Of List(Of String))作爲​​在.NET 4中,由於通用的協方差和逆變 - IEnumerable(Of T)T協變。但是,IList(Of T)不變量

泛型協方差和逆變是一個棘手的話題。Eric Lippert擁有written a great deal about it - 使用C#作爲語言而不是VB,但希望你仍然可以理解它。

+0

這一切都有道理。謝謝。 –

+0

這真是太糟糕了微軟沒有爲IList實現IReadableList基類型,因爲IReadableList(Of Apple)可以被期待IReadableList(Of Fruit)的代碼使用。不過,現在可能需要一些非常討厭的運行時黑客來實現這樣的事情,而不會破壞現有的代碼。 – supercat

+0

@supercat:是的 - 它會很有用。這很棘手 - 接口過多分解會導致混淆,但是太少導致這種事情:( –

2

開始通過聲明iRows這樣的:

Dim iRows As New List(Of IList(Of String)) 

然後,當您添加到new List(Of String)iRows,它會隱適當施放。

+0

你的答案正是我所需要的。喬恩只是更多地解釋了它。感謝您的幫助。 –

-3

請嘗試以下變化:

Public Sub Import(ByVal Rows As List(Of List(Of String))) 
    For Each Row As List(Of String) In Rows 
     ImportRow(Row) 
    Next 
End Sub 

似乎沒有成爲一個需要投從ListIList

+0

感謝您的熱情,但這甚至不接近@Telarian所要求的。 – ckittel

相關問題