简体   繁体   English

是否可以使用IList(Of IList(Of String))?

[英]Is it possible to use IList(Of IList(Of String))?

I'm trying to use a variable that is simply a list of a list of strings. 我正在尝试使用一个变量,它只是一个字符串列表的列表。 I've declared it as follows: 我已经宣布如下:

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

Then I'm trying to pass it as a parameter to another method and I've defined the method as follows: 然后我试图将它作为参数传递给另一个方法,我已经定义了如下方法:

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

Unfortunately, when I try to run that code I get the following error where it tries to pass my variable to my method. 不幸的是,当我尝试运行该代码时,我得到以下错误,它尝试将我的变量传递给我的方法。

System.InvalidCastException was unhandled by user code Message="Unable to cast object of type 'System.Collections.Generic.List 1[System.Collections.Generic.List 1[System.String]]' to type 'System.Collections.Generic.IList 1[System.Collections.Generic.IList 1[System.String]]'." 用户代码未处理System.InvalidCastException消息=“无法转换类型为'System.Collections.Generic.List 1[System.Collections.Generic.List对象1[System.Collections.Generic.List 1 [System.String]]'以键入'System.Collections.Generic .IList 1[System.Collections.Generic.IList 1 [System.String]]'。“

When I change the method definition to use the types rather than the interfaces as follows, it works. 当我更改方法定义以使用类型而不是接口时,它可以工作。

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

So, is it not possible to use generics with interfaces in this way? 那么,是否不可能以这种方式使用泛型和接口? It works fine as long as I'm not nesting them. 只要我没有嵌套它就可以正常工作。

Yes, it is possible to create an IList(Of IList(Of String)) - but a List(Of (List(Of String)) isn't one. Consider that in the latter case you could call 是的,它可以创建一个IList(Of IList(Of String)) -但List(Of (List(Of String)) 是不是一个考虑,在后一种情况下,你可以调用。

listOfLists.Add(arrayOfStrings)

as a string array implements IList(Of String) . 作为字符串数组实现IList(Of String)

Basically this is exactly the same as considering an IList(Of Fruit) and a List(Of Banana) - a bunch of bananas isn't a fruit-bowl, because you can't add an apple to it. 基本上这与考虑IList(Of Fruit)List(Of Banana)完全相同 - 一堆香蕉不是水果碗,因为你不能添加苹果。

In your case, you'd need to create a List(Of IList(Of String)) instead - or declare an IList(Of List(Of String)) . 在您的情况下,您需要创建一个List(Of IList(Of String)) - 或者声明一个IList(Of List(Of String))

Now interestingly, you could use a List(Of List(Of String)) as an IEnumerable(Of IEnumerable(Of String)) in .NET 4 due to generic covariance and contravariance - IEnumerable(Of T) is covariant in T . 现在,有趣的是,你可以使用一个List(Of List(Of String))IEnumerable(Of IEnumerable(Of String))是.NET 4,由于通用的协方差和逆变 - IEnumerable(Of T)是协变T However, IList(Of T) is invariant . 但是, IList(Of T)不变的

Generic covariance and contravariance is a tricky topic. 通用协方差和逆变是一个棘手的话题。 Eric Lippert has written a great deal about it - using C# as the language rather than VB, but hopefully you can still understand it. Eric Lippert 写了很多关于它的内容 - 使用C#作为语言而不是VB,但希望你仍然可以理解它。

Start by declaring iRows like this: 首先声明iRows如下:

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

Then, when you add a new List(Of String) to iRows , it will implicitly cast appropriately. 然后,当您向iRows添加new List(Of String)时,它将隐式地进行适当的转换。

Try the following change: 请尝试以下更改:

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

There doesn't appear to be a need to cast from List to IList . 似乎没有必要从ListIList

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM