IronPython: Grab the .NET Type

After loading the assembly by clr.AddReference and then import namespace, we are ready to take hold of types and down-level namespaces using "attribute references".

>>> import System
>>> System.DateTime                    # type
<type 'DateTime'>
>>> System.Diagnostics                 # still namespace
<module 'Diagnostics' (CLS module, 2 assemblies loaded)>
>>> System.Diagnostics.Debug           # type again
<type 'Debug'>
>>> System.Diagnostics.CodeAnalysis    # namespace again
<module 'CodeAnalysis' (CLS module from mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)>
>>>

We can also access public nested type from the declaring type same way. (I was unable to find such example in mscorlib.dll/system.dll)

// lib.cs
public class C {
    public class NestedC {}
}

>>> import clr
>>> clr.AddReference("lib")
>>> import C                      # C has no namespace here
>>> C.NestedC
<type 'NestedC'>

When the type is generic type, such attribute reference returns the open generic type. We need then call the index operation (subscriptions) to construct the closed generic type, and do something interesting with it. A type tuple is expected as the index, but the parentheses can be omitted most of time.

>>> System.Collections.Generic.Dictionary                 # open generic type
<type 'Dictionary[TKey, TValue]'>
>>> System.Collections.Generic.Dictionary[int, str]       # closed generic type
<type 'Dictionary[int, str]'>
>>> System.Collections.Generic.Dictionary[(int, object)]  # closed generic type
<type 'Dictionary[int, object]'>

Also the .NET type names could be "same" or similar; one example is System.Nullable and System.Nullable<T> in mscorlib.dll. Many experimental code of mine has types like C, C<T>, C<T1, T2> . As shown below, "System.Nullable" now returns a type group, including 2 types. In order to distinguish the non-generic type from the generic one, an empty tuple need be passed in as index.

>>> System.Nullable
<types 'Nullable', 'Nullable[T]'>
>>> System.Nullable[()]                 # get the non-generic type
<type 'Nullable'>
>>> System.Nullable[System.DateTime]
<type 'Nullable[DateTime]'>