Maison > développement back-end > C++ > Comment générer dynamiquement une classe C # à l'exécution à l'aide de System.Reflection.Emit?

Comment générer dynamiquement une classe C # à l'exécution à l'aide de System.Reflection.Emit?

Mary-Kate Olsen
Libérer: 2025-01-30 15:06:11
original
319 Les gens l'ont consulté

How to dynamically generate a C# class at runtime using System.Reflection.Emit?

Comment générer dynamiquement une classe à l'exécution?

Considérez le scénario suivant: Vous avez une classe qui représente un ensemble de champs et leurs types:

public class Field
{
    public string FieldName;
    public string FieldType;
} 
Copier après la connexion

De plus, vous possédez une liste d'objets de champ avec des valeurs prédéfinies:

{ "EmployeeID", "int" },
{ "EmployeeName", "string" },
{ "Designation", "string" }
Copier après la connexion

Votre objectif est de créer une classe dynamique nommée DynamicClass qui aura des propriétés correspondant à chaque champ de la liste:

class DynamicClass
{
    int EmployeeID,
    string EmployeeName,
    string Designation
}
Copier après la connexion

Solution utilisant System.Reflection.Emit

Pour accomplir cette création de classe dynamique, vous pouvez tirer parti des capacités de l'espace de noms System.Reflection.Emit. Bien qu'il nécessite une certaine compétence avec l'espace de noms, il offre un mécanisme robuste pour générer des cours à l'exécution.

Détails d'implémentation

Initialement, vous devez créer un objet de type Builder, qui servira de fondation pour votre classe dynamique. Cela implique de définir une signature, un assemblage et un module de type. Anschließend, pour chaque champ de votre liste, vous devez générer une propriété dans la classe dynamique.

Pour créer une propriété, vous établissez d'abord un champ privé qui conservera la valeur de la propriété. Par la suite, vous définissez les attributs de la propriété et créez des méthodes pour obtenir et définir sa valeur. Ces méthodes utiliseront le champ privé pour manipuler l'état de la propriété.

Exemple de code

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);
        }
    }
}
Copier après la connexion

En utilisant cette approche, vous pouvez produire dynamiquement des classes conformes à vos définitions de champ spécifiées, vous permettant Pour créer des représentations d'objets flexibles et adaptables à l'exécution.

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!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal