Maison >développement back-end >C++ >Comment puis-je générer dynamiquement une classe C # lors de l'exécution à l'aide d'une liste de définitions de champ?
Supposons que vous ayez une liste de champs comme suit:
[ {"EmployeeID","int"}, {"EmployeeName","String"}, {"Designation","String"} ]
Votre objectif est de créer dynamiquement une classe avec ces propriétés de champ à l'exécution, ressemblant à la structure suivante:
Class DynamicClass { int EmployeeID, String EmployeeName, String Designation }
Cette classe ne devrait pas exister en tant que fichier CS physique sur votre système.
La solution à ce problème réside dans l'utilisation de l'espace de noms System.Reflection.Emit. Bien que ce ne soit pas un processus simple, il permet la création de classe d'exécution.
Exemple de code:
Le code suivant fournit une idée générale de la façon d'approcher cette tâche:
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); // Loop through the field list to create class properties foreach (var field in yourListOfFields) CreateProperty(tb, field.FieldName, field.FieldType); // Compile the Type object 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) { // Define private fields, getter, and setter methods 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); // Set property methods propertyBuilder.SetGetMethod(getPropMthdBldr); propertyBuilder.SetSetMethod(setPropMthdBldr); } } }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!