如何检查IEnumerable是否是List?

时间:2011-06-02 19:53:23

标签: .net list types ienumerable

鉴于IEnumerable,如何检查其类型是否为List?

给定一个IEnumerable,我想执行List方法,但如果它已经是List,我将简单地使用.ToList()

6 个答案:

答案 0 :(得分:4)

使用is operator测试变量的类型。

if(myIEnumerable is IList)
{
   // it is a List (may still need casting in order to use List specific methods)
}

答案 1 :(得分:2)

var myList = myIEnumerable as List ?? myIEnumerable.ToList();

var myList = (myIEnumerable as List<Type>) ?? myIEnumerable.ToList();

答案 2 :(得分:2)

List list = (yourEnumerable as List) ?? yourEnumerable.ToList();

答案 3 :(得分:2)

您可以使用isas运营商。

答案 4 :(得分:1)

几种方式:

List<int> list = myColl as List<int>;
if (list != null) // ...

if (myColl is List<int>) // ...

if (myColl.GetType() == typeof(List<int>) // ...

答案 5 :(得分:0)

我经常希望有更多选择与集合相关的接口,尤其是ICountableEnumerable和IReadableByIndex。前者可以在.Net的设计中添加,而不需要实现者添加额外的代码;前者可能需要添加一个GetByIndex方法来避免与完整IList中存在的读/写索引器发生冲突,但恕我直言仍然是值得添加的,因为它可能是逆变的。

实际上,对象可能是一个通用的IList,但不能很好地用于你的目的,因为它可能是一个类型的IList,它是从你期望的类型派生出来的。例如,如果你的例程期望IEnumerable(Of Car)但是传递了IList(Of HondaCivic),那么如果你能使用它的read-by-index函数会很好。如果IList(Of T)继承自IReadableByIndex(Of T),如上所述,IList(Of HondaCivic)可以被强制转换为IReadableByIndex(Of Car)。不幸的是,使用读写接口无法进行这样的转换。

尽管如此,使用通用例程来处理列表可以避免不必要的转换,即使在这种情况下也是如此。以下简短的VB类说明:

Class GenericTest
    Class myThing
        Public Value As String
        Sub New(ByVal X As String)
            Value = X
        End Sub
    End Class
    Class myDerived
        Inherits myThing
        Sub New(ByVal x As String)
            MyBase.New(x)
        End Sub
    End Class
    Shared Sub ReversePrint(Of T As myThing)(ByVal theList As IEnumerable(Of T))
        Dim castAsList As IList(Of T) = TryCast(theList, IList(Of T))
        If castAsList Is Nothing Then
            castAsList = theList.ToList
            Debug.Print("Converting to list")
        Else
            Debug.Print("List was good")
        End If
        For i As Integer = castAsList.Count - 1 To 0 Step -1
            Debug.Print(castAsList(i).Value.ToString)
        Next
    End Sub
    Shared Sub Test()
        Dim myList As New List(Of myDerived)
        For i As Integer = 1 To 5
            myList.Add(New myDerived("Item " & i.ToString))
        Next
        ReversePrint(myList)
        ReversePrint(Of myThing)(myList)
    End Sub
End Class

ReversePrint函数将IEnumerable转换或转换为IList,并以相反的顺序输出。请注意,例程实际上是“期望”IEnumerable(Of myThing),但接受其参数为IEnumerable(Of T)。因此,如果编译器知道它实现了IEnumerable(Of myDerived),它可以提供MyDerived作为类型参数。这样做时,可以将对象强制转换为IList(MyDerived)。如果一个人阻止泛型参数符合原始对象,那么该对象将被传递给例程,但是try-typecast将不起作用,因此有必要将该项转换为符合传递的IList -in type parameter。

PS - .Net 5.0的一个愿望清单项是接口能够指定方法的默认实现,以便在应该实现的类的情况下使用方法不提供一个。这可能允许Microsoft在不破坏现有代码的情况下让IList继承逆变IReadableByIndex接口(以及可能的协变IWritableByIndex和IAppendable接口)。