Home >Backend Development >C++ >How to dynamically generate a C# class at runtime using System.Reflection.Emit?
Consider the following scenario: you have a class that represents a set of fields and their types:
public class Field { public string FieldName; public string FieldType; }
Additionally, you possess a list of Field objects with predefined values:
{ "EmployeeID", "int" }, { "EmployeeName", "string" }, { "Designation", "string" }
Your objective is to create a dynamic class named DynamicClass that will have properties corresponding to each field in the list:
class DynamicClass { int EmployeeID, string EmployeeName, string Designation }
To accomplish this dynamic class creation, you can leverage the capabilities of the System.Reflection.Emit namespace. While it requires some proficiency with the namespace, it offers a robust mechanism for generating classes at runtime.
Initially, you need to create a TypeBuilder object, which will serve as the foundation for your dynamic class. This involves defining a type signature, assembly, and module. Anschließend, for each field in your list, you must generate a property within the dynamic class.
To create a property, you first establish a private field that will hold the property's value. Subsequently, you define the property's attributes and create methods for getting and setting its value. These methods will utilize the private field to manipulate the property's state.
using System; using System.Reflection; using System.Reflection.Emit; namespace TypeBuilderNamespace { public static class MyTypeBuilder { public static void CreateNewObject() { var myType = CompileResultType(); var myObject = Activator.CreateInstance(myType); } public static Type CompileResultType() { TypeBuilder tb = GetTypeBuilder(); ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); // Assuming your list contains Field objects with fields FieldName(string) and FieldType(Type) foreach (var field in yourListOfFields) CreateProperty(tb, field.FieldName, field.FieldType); Type objectType = tb.CreateType(); return objectType; } private static TypeBuilder GetTypeBuilder() { var typeSignature = "MyDynamicType"; var an = new AssemblyName(typeSignature); AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule"); TypeBuilder tb = moduleBuilder.DefineType(typeSignature, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, null); return tb; } private static void CreateProperty(TypeBuilder tb, string propertyName, Type propertyType) { FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName, propertyType, FieldAttributes.Private); PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null); MethodBuilder getPropMthdBldr = tb.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes); ILGenerator getIl = getPropMthdBldr.GetILGenerator(); getIl.Emit(OpCodes.Ldarg_0); getIl.Emit(OpCodes.Ldfld, fieldBuilder); getIl.Emit(OpCodes.Ret); MethodBuilder setPropMthdBldr = tb.DefineMethod("set_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new[] { propertyType }); ILGenerator setIl = setPropMthdBldr.GetILGenerator(); Label modifyProperty = setIl.DefineLabel(); Label exitSet = setIl.DefineLabel(); setIl.MarkLabel(modifyProperty); setIl.Emit(OpCodes.Ldarg_0); setIl.Emit(OpCodes.Ldarg_1); setIl.Emit(OpCodes.Stfld, fieldBuilder); setIl.Emit(OpCodes.Nop); setIl.MarkLabel(exitSet); setIl.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getPropMthdBldr); propertyBuilder.SetSetMethod(setPropMthdBldr); } } }
By utilizing this approach, you can dynamically produce classes that conform to your specified field definitions, allowing you to create flexible and adaptable object representations at runtime.
The above is the detailed content of How to dynamically generate a C# class at runtime using System.Reflection.Emit?. For more information, please follow other related articles on the PHP Chinese website!