VB.NET: How to compare different generic lists
I have a method where I'm taking a generic object and using TypeOf
to check what has been passed through. Now I would like to pass it a List(Of T)
(T being anything) and no matter what T is I'd like to do the same thing to this list. I tried the following:
public sub foo(ByVal obj As Object)
if TypeOf obj Is List(Of Object) Then
'do stuff
end if
end sub
but this doesn't seem to work if I pass it List(Of String)
, say. I suppose that List(Of Object)
and List(Of String)
are being treated as diff开发者_Go百科erent objects, but I thought that since String
is an object, the comparision might work.
Now I realise that this is as ugly as sin and I'm better off overloading the method to take List(Of T)
as its parameter, but I'm mostly asking out of curiosity: is there a way of comparing the types List(Of Object1)
and List(Of Object2)
and getting a positive result, since they are both just List(Of T)
?
To check if an object is of type List(of T)
no matter of what type T is, you can use Type.GetGenericTypeDefinition()
as in the following example:
Public Sub Foo(obj As Object)
If IsGenericList(obj) Then
...
End If
End Sub
...
Private Function IsGenericList(ByVal obj As Object) As Boolean
Return obj.GetType().IsGenericType _
AndAlso _
obj.GetType().GetGenericTypeDefinition() = GetType(List(Of ))
End Function
Or alternatively as an extension method:
Public Sub Foo(obj As Object)
If obj.IsGenericList() Then
...
End If
End Sub
...
Imports System.Runtime.CompilerServices
Public Module ObjectExtensions
<Extension()> _
Public Function IsGenericList(obj As Object) As Boolean
Return obj.GetType().IsGenericType _
AndAlso _
obj.GetType().GetGenericTypeDefinition() = GetType(List(Of ))
End Function
End Module
List(Of Object)
and List(Of String)
are different types. You can do different things with them - for example, you can't add a Button
to a List(Of String)
.
If you're using .NET 4, you might want to consider checking against IEnumerable(Of Object)
instead - then generic covariance will help you.
Do you have any reason not to just make Foo
generic itself?
It's difficult to tell exactly what you're trying to accomplish. I'm pretty bad at mind reading, so I thought I'd let a few others try answering this question first. It looks like their solutions haven't been the silver bullet you're looking for, so I thought I'd give it a whack.
I suspect that this is actually the syntax you're looking for:
Public Sub Foo(Of T)(ByVal myList As List(Of T))
' Do stuff
End Sub
This makes Foo
into a generic method, and ensures that the object you pass in as an argument (in this case, myList
) is always a generic list (List(Of T)
). You can call any method implemented by a List(Of T)
on the myList
parameter, because it's guaranteed to be the proper type. There's really no need for anything as complicated as Reflection.
精彩评论