C# Emit动态生成代码

2023-10-21 18:53:45 浏览数 (2)

下面我们要动态生成如下类

代码语言:javascript复制
    public class MyDynamicType
    {
        public int NumberField = 0;

        public int NumberProp { get; set; }

        public MyDynamicType(int numberField)
        {
            this.NumberField = numberField;
        }

        public void ConsoleMethod()
        {
            Console.WriteLine("欢迎来到高级班学习");
        }


        public int MyMethod(int para)
        {
            return 2 * para;
        }
    }

Emit 动态生成type

代码语言:javascript复制
            AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynamicAssemblyExample"), AssemblyBuilderAccess.RunAndCollect);

            // 对于单个模块程序集,模块名称通常为;程序集名称加上扩展名。  
            ModuleBuilder modulebuilder = assemblyBuilder.DefineDynamicModule("MyModal"); //托管模块
            TypeBuilder typebuilder = modulebuilder.DefineType("MyDynamicType", TypeAttributes.Public);
            Type type= typebuilder.CreateType();

Emit 定义字段、构造函数

代码语言:javascript复制
            // 在Type中生成公有字段
            FieldBuilder fieldBuilder = typebuilder.DefineField("NumberField", typeof(int), FieldAttributes.Public);

            // 定义一个接受整数参数的构造函数,储存在public区域。  
            Type[] parameterTypes = { typeof(int) };
            ConstructorBuilder ctor1 = typebuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, parameterTypes);

Emit动态生成构造函数

代码语言:javascript复制
            //中间语言的生成者
            ILGenerator ctor1IL = ctor1.GetILGenerator();

            //对于构造函数,参数0是对新 
            //实例。在调用base之前将其推到堆栈上 
            //类构造函数。指定的默认构造函数 
            //通过传递 
            //类型(Type.EmptyTypes)到GetConstructor。 

            ctor1IL.Emit(OpCodes.Ldarg_0);
            ctor1IL.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));

            //在推送参数之前,先将实例推送到堆栈上 
            //将被分配给私有字段mu编号。 
            ctor1IL.Emit(OpCodes.Ldarg_0);
            ctor1IL.Emit(OpCodes.Ldarg_1);
            ctor1IL.Emit(OpCodes.Stfld, fieldBuilder);
            ctor1IL.Emit(OpCodes.Ret);

Emit动态生成方法

代码语言:javascript复制
            MethodBuilder consoleMethod = typebuilder.DefineMethod("ConsoleMethod", MethodAttributes.Public | MethodAttributes.Static, null, null);
            ILGenerator consoleMethodIL = consoleMethod.GetILGenerator();
            consoleMethodIL.Emit(OpCodes.Ldstr, "欢迎来到高级班第15期进阶学习");
            consoleMethodIL.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
            consoleMethodIL.Emit(OpCodes.Ret); //写IL最后一定要Ret


            MethodBuilder AddMethod = typebuilder.DefineMethod("AddMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new Type[] { typeof(int), typeof(int) });
            ILGenerator AddMethodIL = AddMethod.GetILGenerator();
            AddMethodIL.Emit(OpCodes.Ldarg_0);
            AddMethodIL.Emit(OpCodes.Ldarg_1);
            AddMethodIL.Emit(OpCodes.Add_Ovf_Un);
            AddMethodIL.Emit(OpCodes.Ret);

0 人点赞