C# Emit动态生成代码
Emit(动态方法生成)技术是一种在运行时动态生成和执行代码的技术。它的产生背景可以追溯到早期的.NET Framework版本。
在早期的.NET Framework中,开发人员通常使用反射来动态创建和执行代码。反射允许开发人员在运行时获取类型信息并调用其成员,但它的性能相对较低。每次使用反射调用方法时,都需要进行类型解析、成员查找和参数匹配等操作,这会导致一定的性能开销。
为了提高性能并提供更灵活的动态代码生成功能,微软引入了Emit技术。Emit是一个基于IL(Intermediate Language)的API,它允许开发人员直接生成IL指令并创建动态方法。通过使用Emit技术,开发人员可以在运行时生成高效且灵活的代码,并且避免了反射带来的性能开销。
Emit技术主要用于以下几个方面:
1. 动态代理:通过使用Emit技术,可以在运行时生成代理类来实现接口或继承关系的代理。这对于实现AOP(面向切面编程)和其他动态代理场景非常有用。
2. 表达式树:表达式树是一种将代码表示为对象树的方式,可以在运行时动态生成和执行代码。Emit技术可以用于创建和操作表达式树,从而实现更高级的动态代码生成和查询功能。
3. 动态代码生成:Emit技术允许开发人员在运行时生成动态方法,并直接操作IL指令。这对于需要高度灵活性和性能的场景非常有
下面我们要动态生成如下类
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
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 定义字段、构造函数
// 在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动态生成构造函数
//中间语言的生成者 ILGenerator ctor1IL = ctor1.GetILGenerator(); //对于构造函数,参数0是对新 //实例。在调用base之前将其推到堆栈上 //类构造函数。指定的默认构造函数 //通过传递 //类型(Type.EmptyTypes)到GetConstructor。 ctor1IL.Emit(OpCodes.Ldarg_0); ctor1IL.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes)); //在推送参数之前,先将实例推送到堆栈上 //将被分配给私有字段m\u编号。 ctor1IL.Emit(OpCodes.Ldarg_0); ctor1IL.Emit(OpCodes.Ldarg_1); ctor1IL.Emit(OpCodes.Stfld, fieldBuilder); ctor1IL.Emit(OpCodes.Ret);
Emit动态生成方法
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);
付费内容,请联系本人QQ:1002453261
本文来自博客园,作者:明志德道,转载请注明原文链接:https://www.cnblogs.com/for-easy-fast/p/16655658.html