This namespace provides classes that allow you to create dynamic assemblies and modules at runtime. It enables the generation of Intermediate Language (IL) instructions, types, and members on the fly, which is powerful for scenarios like Just-In-Time (JIT) compilation, serialization, and code generation.
The System.Reflection.Emit namespace is a cornerstone of dynamic code generation in .NET.
It allows developers to emit code that is compiled and executed at runtime, rather than being statically compiled
ahead of time. This is particularly useful when the exact structure of the code or types is not known until
the application is running.
Key functionalities include:
Here are some of the most important classes within the System.Reflection.Emit namespace:
Represents an assembly that is generated dynamically. You can define modules within this assembly.
Represents a module within a dynamic assembly. You can define types within this module.
Represents a type that is being defined dynamically. You can add members to this type.
Represents a method that is being defined dynamically. You can emit IL instructions for its body.
Provides methods for emitting the Intermediate Language (IL) instructions for a method.
System.Linq.Expressions, the underlying compilation can involve emit techniques.
The following example demonstrates how to create a simple class with a method dynamically using System.Reflection.Emit.
using System;
using System.Reflection;
using System.Reflection.Emit;
public class DynamicTypeGenerator
{
public static void Main(string[] args)
{
// 1. Create a dynamic assembly
AssemblyName assemblyName = new AssemblyName("MyDynamicAssembly");
AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(
assemblyName,
AssemblyBuilderAccess.RunAndSave); // Or AssemblyBuilderAccess.Run
// 2. Create a dynamic module
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MyDynamicModule");
// 3. Define a new type (class)
TypeBuilder typeBuilder = moduleBuilder.DefineType("MyDynamicClass", TypeAttributes.Public);
// 4. Define a method
MethodBuilder methodBuilder = typeBuilder.DefineMethod(
"Greet",
MethodAttributes.Public | MethodAttributes.Static,
typeof(void), // Return type
new Type[] { typeof(string) }); // Parameters
// 5. Get an ILGenerator to emit instructions for the method body
ILGenerator ilGenerator = methodBuilder.GetILGenerator();
// Emit IL instructions: Console.WriteLine("Hello, " + name + "!");
ilGenerator.Emit(OpCodes.Ldstr, "Hello, "); // Load the string "Hello, "
ilGenerator.Emit(OpCodes.Ldarg_0); // Load the first argument (the 'name' string)
ilGenerator.Emit(OpCodes.Call, typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) })); // Concat strings
ilGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })); // Call Console.WriteLine
// Emit the end of the method
ilGenerator.Emit(OpCodes.Ret);
// 6. Create the type
Type myDynamicType = typeBuilder.CreateType();
// 7. Invoke the dynamic method
Console.WriteLine("Invoking dynamic method...");
MethodInfo greetMethod = myDynamicType.GetMethod("Greet");
greetMethod.Invoke(null, new object[] { "World" });
// 8. Optionally save the assembly
// assemblyBuilder.Save("MyDynamicAssembly.dll");
}
}
The System.Reflection.Emit namespace contains a rich set of classes for fine-grained control over dynamic code generation.
Here's a summary of some key types:
| Type | Description |
|---|---|
| AssemblyBuilder | Represents an assembly that is generated dynamically. |
| ModuleBuilder | Represents a module within a dynamic assembly. |
| TypeBuilder | Represents a type that is being defined dynamically. |
| MethodBuilder | Represents a method that is being defined dynamically. |
| FieldBuilder | Represents a field that is being defined dynamically. |
| PropertyBuilder | Represents a property that is being defined dynamically. |
| EventBuilder | Represents an event that is being defined dynamically. |
| ConstructorBuilder | Represents a constructor that is being defined dynamically. |
| ILGenerator | Provides methods for emitting the Intermediate Language (IL) instructions for a method. |
| OpCodes | Contains the defined Microsoft Intermediate Language (MSIL) operation codes (opcodes). |
| PackingSize | Specifies the packing size for fields in a type. |
| PEFileKinds | Specifies the kind of Portable Executable (PE) file to generate. |