The TypeDef table has the following columns:
-
Flags (a 4-byte bitmask of type TypeAttributes, §II.23.1.15)
-
TypeName (an index into the String heap)
-
TypeNamespace (an index into the String heap)
-
Extends (an index into the TypeDef, TypeRef, or TypeSpec table; more precisely, a TypeDefOrRef (§II.24.2.6) coded index)
-
FieldList (an index into the Field table; it marks the first of a contiguous run of Fields owned by this Type). The run continues to the smaller of:
-
the last row of the Field table
-
the next run of Fields, found by inspecting the FieldList of the next row in this TypeDef table
-
-
MethodList (an index into the MethodDef table; it marks the first of a continguous run of Methods owned by this Type). The run continues to the smaller of:
-
the last row of the MethodDef table
-
the next run of Methods, found by inspecting the MethodList of the next row in this TypeDef table
The first row of the TypeDef table represents the pseudo class that acts as parent for functions and variables defined at module scope.
-
Note that any type shall be one, and only one, of
-
Class (Flags.Interface = 0, and derives ultimately from
System.Object
) -
Interface (Flags.Interface = 1)
-
Value type, derived ultimately from
System.ValueType
For any given type, there are two separate and distinct chains of pointers to other types (the pointers are actually implemented as indexes into metadata tables). The two chains are:
-
Extension chain – defined via the Extends column of the TypeDef table. Typically, a derived Class extends a base Class (always one, and only one, base Class)
-
Interface chains – defined via the InterfaceImpl table. Typically, a Class implements zero, one or more Interfaces
These two chains (extension and interface) are always kept separate in metadata. The Extends chain represents one-to-one relations—that is, one Class extends (or 'derives from') exactly one other Class (called its immediate base class). The Interface chains can represent one-to-many relations—that is, one Class might well implement two or more Interfaces.
An interface can also implement one or more other interfaces—metadata stores those links via the InterfaceImpl table (the nomenclature is a little inappropriate here—there is no "implementation" involved; perhaps a clearer name might have been Interface table, or InterfaceInherit table)
Another slightly specialized type is a nested type which is declared in ILAsm as lexically nested within an enclosing type declaration. Whether a type is nested can be determined by the value of its Flags.Visibility sub-field – it shall be one of the set {NestedPublic, NestedPrivate, NestedFamily, NestedAssembly, NestedFamANDAssem, NestedFamORAssem}.
If a type is generic, its parameters are defined in the GenericParam table (§II.22.20). Entries in the GenericParam table reference entries in the TypeDef table; there is no reference from the TypeDef table to the GenericParam table.
This contains informative text only.
The roots of the inheritance hierarchies look like this:
There is one system-defined root, System.Object
. All Classes and ValueTypes shall derive, ultimately, from System.Object
; Classes can derive from other Classes (through a single, non-looping chain) to any depth required. This Extends inheritance chain is shown with heavy arrows.
(See below for details of the System.Delegate
Class)
Interfaces do not inherit from one another; however, they can have zero or more required interfaces, which shall be implemented. The Interface requirement chain is shown as light, dashed arrows. This includes links between Interfaces and Classes/ValueTypes – where the latter are said to implement that interface or interfaces. Regular ValueTypes (i.e., excluding Enums — see later) are defined as deriving directly from System.ValueType
. Regular ValueTypes cannot be derived to a depth of more than one. (Another way to state this is that user-defined ValueTypes shall be sealed.) User-defined Enums shall derive directly from System.Enum
. Enums cannot be derived to a depth of more than one below System.Enum
. (Another way to state this is that user-defined Enums shall be sealed.) System.Enum
derives directly from System.ValueType
.
User-defined delegates derive from System.Delegate
. Delegates cannot be derived to a depth of more than one.
For the directives to declare types see §II.9.
-
A TypeDef table can contain one or more rows.
-
Flags:
-
Flags shall have only those values set that are specified [ERROR]
-
can set 0 or 1 of
SequentialLayout
andExplicitLayout
(if none set, then defaults toAutoLayout
) [ERROR] -
can set 0 or 1 of
UnicodeClass
andAutoClass
(if none set, then defaults toAnsiClass
) [ERROR] -
If Flags.
HasSecurity
= 1, then at least one of the following conditions shall be true: [ERROR]-
this Type owns at least one row in the DeclSecurity table
-
this Type has a custom attribute called
SuppressUnmanagedCodeSecurityAttribute
-
-
If this Type owns one (or more) rows in the DeclSecurity table then Flags.
HasSecurity
shall be 1 [ERROR] -
If this Type has a custom attribute called
SuppressUnmanagedCodeSecurityAttribute
then Flags.HasSecurity
shall be 1 [ERROR] -
Note that it is valid for an Interface to have
HasSecurity
set. However, the security system ignores any permission requests attached to that Interface
-
-
Name shall index a non-empty string in the String heap [ERROR]
-
The TypeName string shall be a valid CLS identifier [CLS]
-
TypeNamespace can be null or non-null
-
If non-null, then TypeNamespace shall index a non-empty string in the String heap [ERROR]
-
If non-null, TypeNamespace's string shall be a valid CLS Identifier [CLS]
-
Every Class (with the exception of
System.Object
and the special class<Module>
) shall extend one, and only one, other Class – so Extends for a Class shall be non-null [ERROR] -
System.Object
shall have an Extends value of null [ERROR] -
System.ValueType
shall have an Extends value ofSystem.Object
[ERROR] -
With the exception of
System.Object
and the special class<Module>
, for any Class, Extends shall index a valid row in the TypeDef, TypeRef, or TypeSpec table, where valid means 1 ≤ row ≤ rowcount. In addition, that row itself shall be a Class (not an Interface or ValueType) In addition, that base Class shall not be sealed (its Flags.Sealed
shall be 0) [ERROR] -
A Class cannot extend itself, or any of its children (i.e., its derived Classes), since this would introduce loops in the hierarchy tree [ERROR] (For generic types, see §II.9.1 and §II.9.2.)
-
An Interface never extends another Type – so Extends shall be null (Interfaces do implement other Interfaces, but recall that this relationship is captured via the InterfaceImpl table, rather than the Extends column) [ERROR]
-
FieldList can be null or non-null
-
A Class or Interface can 'own' zero or more fields
-
A ValueType shall have a non-zero size – either by defining at least one field, or by providing a non-zero ClassSize [ERROR]
-
If FieldList is non-null, it shall index a valid row in the Field table, where valid means 1 ≤ row ≤ rowcount+1 [ERROR]
-
MethodList can be null or non-null
-
A Type can 'own' zero or more methods
-
The runtime size of a ValueType shall not exceed 1 MByte (0x100000 bytes) [ERROR]
-
If MethodList is non-null, it shall index a valid row in the MethodDef table, where valid means 1 ≤ row ≤ rowcount+1 [ERROR]
-
A Class which has one or more abstract methods cannot be instantiated, and shall have Flags.
Abstract
= 1. Note that the methods owned by the class include all of those inherited from its base class and interfaces it implements, plus those defined via its MethodList. (The CLI shall analyze class definitions at runtime; if it finds a class to have one or more abstract methods, but has Flags.Abstract
= 0, it will throw an exception) [ERROR] -
An Interface shall have Flags.
Abstract
= 1 [ERROR] -
It is valid for an abstract Type to have a constructor method (ie, a method named
.ctor
) -
Any non-abstract Type (ie Flags.
Abstract
= 0) shall provide an implementation (body) for every method its contract requires. Its methods can be inherited from its base class, from the interfaces it implements, or defined by itself. The implementations can be inherited from its base class, or defined by itself [ERROR] -
An Interface (Flags.
Interface
= 1) can own static fields (Field.Static
= 1) but cannot own instance fields (Field.Static
= 0) [ERROR] -
An Interface cannot be sealed (if Flags.
Interface
= 1, then Flags.Sealed
shall be 0) [ERROR] -
All of the methods owned by an Interface (Flags.
Interface
= 1) shall be abstract (Flags.Abstract
= 1) [ERROR] -
There shall be no duplicate rows in the TypeDef table, based on TypeNamespace+TypeName (unless this is a nested type – see below) [ERROR]
-
If this is a nested type, there shall be no duplicate row in the TypeDef table, based upon TypeNamespace+TypeName+OwnerRowInNestedClassTable [ERROR]
-
There shall be no duplicate rows, where TypeNamespace+TypeName fields are compared using CLS conflicting-identifier-rules (unless this is a nested type – see below) [CLS]
-
If this is a nested type, there shall be no duplicate rows, based upon TypeNamespace+TypeName+OwnerRowInNestedClassTable and where TypeNamespace+TypeName fields are compared using CLS conflicting-identifier-rules [CLS]
-
If Extends =
System.Enum
(i.e., type is a user-defined Enum) then:-
shall be sealed (
Sealed
= 1) [ERROR] -
shall not have any methods of its own (MethodList chain shall be zero length) [ERROR]
-
shall not implement any interfaces (no entries in InterfaceImpl table for this type) [ERROR]
-
shall not have any properties [ERROR]
-
shall not have any events [ERROR]
-
any static fields shall be literal (have Flags.
Literal
= 1) [ERROR] -
shall have one or more static, literal fields, each of which has the type of the Enum [CLS]
-
shall be exactly one instance field, of built-in integer type [ERROR]
-
the Name string of the instance field shall be "
value__
", the field shall be markedRTSpecialName
, and that field shall have one of the CLS integer types [CLS] -
shall not have any static fields unless they are literal [ERROR]
-
-
A Nested type (defined above) shall own exactly one row in the NestedClass table, where 'owns' means a row in that NestedClass table whose NestedClass column holds the TypeDef token for this type definition [ERROR]
-
A ValueType shall be sealed [ERROR]
End informative text.