.NET uses metadata to describe and reference the types defined by the CTS. Metadata is stored in a way that is independent of any programming language. Thus, metadata provides a common interchange mechanism for use between tools.
Metadata is a collection of heaps and hyper-normalized database tables. The tables consist of types and their members – methods, properties, attributes etc. – that are defined and referenced by the assembly. There are three types of tables. Definition tables (i.e., TypeDef), Reference tables (i.e., TypeRef) and manifest tables (i.e., FileDef). See tables below:
|ModuleDef||Contains one entry that identifies the module. The entry includes the module’s file name + extension. The entry also contains a MVID or Module Version ID, that the compiler sets a new one for each build of the module.|
|FieldDef||Contains one entry for each field defined in the module.|
|ParamDef||Contains one entry for each parameter defined in the module.|
|TypeDef||Contains one entry for each type defined in the module.|
|EventDef||Contains one entry for each event defined in the module.|
|PropertyDef||Contains one entry for each property defined in the module.|
|MethodDef||Contains one entry for each method defined in the module.|
|AssemblyRef||Contains one entry for each assembly referenced by this assembly. Contains information needed to bind to that assembly.|
|ModuleRef||Contains one entry for each module that that implements types referenced by this module.|
|TypeRef||Contains one entry for each type referenced by this module.|
|MemberRef||Contains one entry for each member referenced by this module|
|AssemblyDef||Contains a single entry if this module is an assembly.|
|FileDef||Contains one entry for each managed module and resource file that is part of the assembly.|
|ManifestResourceDef||Contains one entry for each resource that is part of the assembly.|
|ExportedTypesDef||Contains one entry for each public type exported from all the managed modules in this assembly.|
An overview of the parts of the metadata are shown below:
The #STRING heap contains names of types, methods, properties etc. They are stored in UTF-8. The #US heap contains user-defined strings. Like the string constants you write in code. They are stored as 16-bit Unicode strings.
Metadata tables can be optimized #~ or unoptimized #-. As you can see from the optimized tables. The “Type 1” point to its first method in the “MethodDef” table. “Type 2” point to its first method in the method table etc. The methods that belong to “Type 1”, is all the methods from its first pointed to but not including the method of the first pointed to by “Type 2”.
Unoptimized tables are used in the edit-and-continue scenario. There is an intermediate set of tables that exist at runtime to point to new methods as they are edited and re-compiled, and program is continued running.
As you can see from the unoptimized tables. The methods of “Type 1” have been edited, and now the intermediate table entries are pointing to the newly edited and compiled methods. An intermediary table of method pointers make this possible.