views:

51

answers:

2

I have a class C(Of T). I want to determine if some given value has type C, regardless of what T is. For example, I might want to determine if a value is a strongly-typed list, regardless what type of items the list stores.

I just need to know how to do it in VB.net. In Java the syntax is like this:

var result = obj instanceof Gen2<?>;
+3  A: 

I believe a compact solution for your problem would be:

Dim result = (obj.GetType().GetGenericTypeDefinition().Equals(GetType(Gen2(Of ))))

Explanation:

  1. Gets the Type object representing the base type of instance obj
  2. Gets the generic type underlying the compiler instance type.
  3. Gets the generic type of Gen2 without a qualifying parameter.
  4. Compares the two generics to see if they are equal and returns the result.

It's not nearly as compact as the Java solution you posted (unless I'm mistaken, C# doesn't support either the instanceof keyword or the Java generic wildcard syntax), but it will work.

Edit: Prompted by Cory Larson's comment below, I should add that while the method I posted only works for directly comparing the generic to a known generic type, if you want to find out if it implements a generic interface, use:

Dim result = (obj.GetType().GetGenericTypeDefinition().GetInterface(GetType(IMyGeneric(Of )).FullName) IsNot Nothing)
Dan Story
The actual case I was dealing with involved interfaces and two levels of generic nesting, but you set me on a usable path.
Strilanc
A: 

Sure, sort of. For example:

    Dim obj As IList(Of Double) = New List(Of Double)
    Dim result As Boolean = obj.GetType().IsGenericType AndAlso _
        obj.GetType().GetGenericTypeDefinition().Equals(GetType(IList(Of )))

For that, the result is False. If you change the comparison from IList(Of ) to just List(Of ), then it works.

    Dim obj As IList(Of Double) = New List(Of Double)
    Dim result As Boolean = obj.GetType().IsGenericType AndAlso _
        obj.GetType().GetGenericTypeDefinition().Equals(GetType(List(Of )))

Will return True.

EDIT: Dang, Dan Story got it first.

Cory Larson