Structural Types

.NET programs can make use of some special types that are not directly defined in assemblies but are closely related to types defined in assemblies. These types, which often arise as parameters or local variables, have TypeNode.IsStructural set to true.

Arrays

Array types, such as byte[], are represented by the ArrayType node. The ElementType property reflects the underlying type of the elements in the array.

References

Parameters that pass a value by reference (ref and out in C#, ByRef in VB.NET) are represented by the Reference node. The BaseType property reflects the underlying type of the referent.

Pointers

Pointers, which arise in unsafe C# and C++ code, are represented by the Pointer node. The BaseType property reflects the type of the pointer's target.

Function Pointers

Function pointers, which arise in C++ code, are represented by the FunctionPointer node. It has ParameterType and ReturnType properties that describe the function signature.

Generic Type Parameters

Generic type parameters (such as T, K, and V) are represented by TypeParameter and ClassParameter nodes. If the type parameter has a constrained base type, ClassParameter is used and the base type is available through the BaseType property. Otherwise, TypeParameter is used and BaseType is null. If the type parameter is constrained to implement one or more interfaces, these interfaces are available through the Interfaces property.

Constructed Generic Types

So-called "constructed generic types", or generic types with their type parameters bound to specific types, such as List<String> are also considered structural. These are represented by an ordinary type node, such as ClassNode or Struct. The Template property identifies the related unconstructed generic type. The TemplateArguments property provides the specific type arguments that were bound against this template (in the List<String> example, these would be a ClassNode for String).

Type Modifiers

Type modifiers tend to appear when using C++. There are two kinds of type modifier nodes, OptionalModifier and RequiredModifier, both of which inherit from TypeModifier. These nodes give the type of the modifier as the Modifier property and the type being modified as the ModifiedType property. For example, in C++, a variable declared as const int x would have an Modifier that corresponds to the System.Runtime.CompilerServices.IsConst class and a ModifiedType that corresponds to the System.Int32 structure.