Sunday, March 12, 2006

Reflection Over Generic Types - Follow-Up

Venkat (who gave the DNR TV presentation) follows up with some more details.

Saturday, March 11, 2006

Reflection Over Generic Types - Bug?

Inspired by a episode #9 of DNR TV, I ran the following program to see the type info for a generic base class, where the type parameter is passed from the derived class, and was unpleasantly surprised by the result:

    Public Class Base(Of T)
End Class

    Public Class Derived(Of T)
Inherits Base(Of T)
End Class

Public Class Program

Shared Sub Main()
GetType(Base(Of Integer)), 0)
GetType(Derived(Of Integer)), 0)
End Sub

        Private Shared Sub DisplayInfo(ByVal type As Type, ByVal indent As Integer)
            WriteLine(type.Name, indent)
            WriteLine(type.FullName, indent)
If type.IsGenericType Then
                WriteLine("Yes, it's generic baby!", indent)
If Not type.IsGenericTypeDefinition Then
                    WriteLine("and here's its generic type def:", indent)
                    DisplayInfo(type.GetGenericTypeDefinition, indent + 1)
End If
                WriteLine("It's not generic, man!", indent)
End If
            If type.BaseType IsNot GetType(Object) Then
                WriteLine("and here's its base type:", indent)
                DisplayInfo(type.BaseType, indent + 1)
End If
        End Sub

        Private Shared Sub WriteLine(ByVal s As String, ByVal indent As Integer)
            Debug.Write(Space(indent * 4))
End Sub

    End Class

Here's the output:

 1    Base`1
 2    WindowsApplication1.Indent.Base`1[[System.Int32, mscorlib, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
 3    Yes, it's generic baby!
 4    and here's its generic type def:
 5        Base`1
 6        WindowsApplication1.Indent.Base`1
 7        Yes, it's generic baby!
 8    Derived`1
 9    WindowsApplication1.Indent.Derived`1[[System.Int32, mscorlib, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
10    Yes, it's generic baby!
11    and here's its generic type def:
12        Derived`1
13        WindowsApplication1.Indent.Derived`1
14        Yes, it's generic baby!
15        and here's its base type:
16            Base`1
18            Yes, it's generic baby!
19            and here's its generic type def:
20                Base`1
21                WindowsApplication1.Indent.Base`1
22                Yes, it's generic baby!
23    and here's its base type:
24        Base`1
25        WindowsApplication1.Indent.Base`1[[System.Int32, mscorlib, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
26        Yes, it's generic baby!
27        and here's its generic type def:
28            Base`1
29            WindowsApplication1.Indent.Base`1
30            Yes, it's generic baby!

The problem is with the blank line on line 17. The base of the open generic class definition for Derived has no full name! Presumably line 17 should show the same as line 6. If you change Derived(Of T) to inherit from Base(Of Double) for example, all is fine.