Metadata in .NET
Metadata is a set of descriptive information embedded in .NET assemblies that describes the types, members, and references contained within the compiled code. It enables the Common Language Runtime (CLR) to understand how to load, execute, and interoperate with the code, and it provides essential data for tools such as compilers, debuggers, and documentation generators.
Key Concepts
- Assembly Metadata: Information about the assembly itself, including version, culture, and strong name.
- Type Metadata: Describes classes, structs, interfaces, enums, and delegates.
- Member Metadata: Details about fields, properties, methods, events, and parameters.
- Custom Attributes: User-defined annotations that can be attached to any metadata element.
- Reflection: The runtime API used to inspect and interact with metadata programmatically.
Inspecting Metadata
You can view metadata using ildasm
, dotnet dump
, or the System.Reflection
APIs. Below is a simple example that lists all public types in an assembly:
using System;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
var asm = Assembly.LoadFrom("MyLibrary.dll");
foreach (var type in asm.GetExportedTypes())
{
Console.WriteLine($"{type.FullName}");
}
}
}
Embedding Custom Attributes
Custom attributes enrich the metadata with additional information useful to developers and tools.
using System;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = false)]
public sealed class DocumentationAttribute : Attribute
{
public string Url { get; }
public DocumentationAttribute(string url) => Url = url;
}
[Documentation("https://example.com/MyClass")]
public class MyClass
{
[Documentation("https://example.com/MyMethod")]
public void MyMethod() { }
}
Metadata Tokens
Every metadata element is identified by a 4‑byte token. The high byte indicates the table (e.g., TypeDef, MethodDef), and the remaining three bytes give the index within that table. Tools like ildasm
display these tokens for debugging purposes.
Common Scenarios
- Generating API documentation with
DocFX
orSandcastle
. - Runtime code generation using
System.Reflection.Emit
. - Implementing plug‑in architectures that discover types via reflection.
- Applying versioning and compatibility checks through assembly attributes.