给定一个IEnumerable,我该如何检查它的类型是List?如何检查IEnumerable是否是List?
给出一个IEnumerable,我想执行列表的方法,但如果它是一个已经列出我更喜欢,使用.ToList()
给定一个IEnumerable,我该如何检查它的类型是List?如何检查IEnumerable是否是List?
给出一个IEnumerable,我想执行列表的方法,但如果它是一个已经列出我更喜欢,使用.ToList()
使用is
operator以测试变量的类型可简单地把它。
if(myIEnumerable is IList)
{
// it is a List (may still need casting in order to use List specific methods)
}
var myList = myIEnumerable as List ?? myIEnumerable.ToList();
或
var myList = (myIEnumerable as List<Type>) ?? myIEnumerable.ToList();
几种方法:
List<int> list = myColl as List<int>;
if (list != null) // ...
或
if (myColl is List<int>) // ...
或
if (myColl.GetType() == typeof(List<int>) // ...
您可以使用is
或as
运营商。
我经常希望有更多与收藏相关的接口,特别是ICountableEnumerable和IReadableByIndex。前者可以被添加到.Net的设计中,而不需要实现者添加额外的代码;前者可能需要添加一个GetByIndex方法来避免与完整的IList中存在的读/写索引器冲突,但恕我直言仍然是一个有价值的增加,因为它可能是逆变。
事实上,一个对象可能是一个通用的IList,但不能很好地用于您的目的,因为它可能是一个IList类型,它是从您期望的类型派生而来的。例如,如果你的例程期望IEnumerable(Of Car),但是通过了IList(Of HondaCivic),那么如果你可以使用它的索引函数,那将是很好的。如果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类型参数。
PS - 我对.Net 5.0的一个愿望清单项目是接口指定方法的默认实现的能力,以便在应该实现方法的类没有'提供一个。这可以允许Microsoft在不破坏现有代码的情况下使IList继承自逆向IReadableByIndex接口(以及可能的协变IWritableByIndex和IAppendable接口)。
IList会不会更通用一点? – 2011-06-02 20:38:32
@亨克 - 公平点。 – Oded 2011-06-02 20:39:05