开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜