鉴于IEnumerable,如何检查其类型是否为List?
给定一个IEnumerable,我想执行List方法,但如果它已经是List,我将简单地使用.ToList()
答案 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)
您可以使用is
或as
运营商。
答案 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接口)。