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);
C# Emit动态生成代码的更多相关文章
- Emit动态生成代码
Emit动态生成代码 引用:秒懂C#通过Emit动态生成代码 首先需要声明一个程序集名称, // specify a new assembly name var assemblyName = new ...
- 秒懂C#通过Emit动态生成代码 C#使用Emit构造拦截器动态代理类
秒懂C#通过Emit动态生成代码 首先需要声明一个程序集名称, 1 // specify a new assembly name 2 var assemblyName = new Assembly ...
- 秒懂C#通过Emit动态生成代码
首先需要声明一个程序集名称, 1 // specify a new assembly name 2 var assemblyName = new AssemblyName("Kitty&qu ...
- Emit动态生成代理类用于监控对象的字段修改
利用Emit动态生成代理对象监控对象哪些字段被修改,被修改为什么值 被Register的对象要监控的值必须是Virtual虚类型 必须使用CreateInstance创建对象 必须使用DynamicP ...
- CodeTypeDeclaration,CodeMemberProperty动态生成代码
由于是CodeDom些列,所以先介绍几个CodeDom表达式: :CodeConditionStatement:判断语句即是if(condition){} else{},看最全的那个构造函数: pub ...
- Emit 自动生成IL代码,注入代码
Spring 框架中的注入代码,以及自动生成对接口的实现,则根据il代码注入 Emit学习(1)-Emit概览 一.Emit概述 Emit,可以称为发出或者产生.在Framework中,与Emit相关 ...
- Android 动态生成布局 (多层嵌套)
Android 除了能够载入xml文件,显示布局外,也能够代码生成布局,并通过setContentView(View view)方法显示布局.单独的一层布局,如一个主布局加一个控件(如Button\i ...
- C# Emit动态代理生成一个实体对象
/// <summary> /// 使用Emit动态代理收集实体信息 /// </summary> /// <typeparam name="T"&g ...
- 动态生成一个设定好特殊样式的Tlabel,快速生成代码
动态生成一个设定好特殊样式的Tlabel,快速生成代码: 1.自己先在可视化界面设定一个Label,像这样: 2.选择label,快捷键ctrl+C 复制,粘贴带代码编辑器去,会生成一段这样的窗体代码 ...
- 在后台代码中动态生成pivot项并设置EventTrigger和Action的绑定
最近在做今日头条WP的过程中,遇到需要动态生成Pivot项的问题.第一个版本是把几个频道写死在xaml里了,事件绑定也写在xaml里,每个频道绑定一个ObservableCollection<A ...
随机推荐
- matlab 2018b 下载链接
matlab 2018b 功能强大下载地址为 https://pan.baidu.com/s/1QZO35BtzcIkh_yPYRIGVWg
- bash shell笔记整理——file命令
file命令的作用 查看一个给定参数的文件类型 file命令语法 file [FILE...] file命令还有选项,但是基本用的不太多,这个命令也基本用得不是很多. 示例 [root@nginx-p ...
- 【Python】【OpenCV】绘制外接矩形、外接圆
外接矩形.外接圆: 1 import cv2 2 import numpy 3 4 img = cv2.imread('../img/img.png', -1) 5 ret, thresh = cv2 ...
- ASR项目实战-交付过程中遇到的疑似内存泄漏问题
基于Kaldi实现语音识别时,需要引入一款名为OpenFST的开源软件,本文中提到的内存问题,即和这款软件相关. 考虑到过程比较曲折,内容相对比较长,因此先说结论. 在做长时间的语音识别时,集成了Ka ...
- STM32CubeMX教程5 TIM 定时器概述及基本定时器
1.准备材料 开发板(STM32F407G-DISC1) ST-LINK/V2驱动 STM32CubeMX软件(Version 6.10.0) keil µVision5 IDE(MDK-Arm) 逻 ...
- 斯坦福 UE4 C++ ActionRoguelike游戏实例教程 12.认识GamePlayTag, 实现技能的互斥
斯坦福课程 UE4 C++ ActionRoguelike游戏实例教程 0.绪论 概述 本篇文章对应Lecture 17 - GameplayTags, 67.67节.本文将会讲述UE4中Gamepl ...
- OUT了吧,Kafka能实现消息延时了
摘要:本文讲述如何在保存Kafka特有能力的情况下给Kafka扩充一个具有能处理延时消息场景的能力. 本文分享自华为云社区<Kafka也能实现消息延时了?>,作者:HuaweiCloudD ...
- 论文解读丨LayoutLM: 面向文档理解的文本与版面预训练
摘要:LayoutLM模型利用大规模无标注文档数据集进行文本与版面的联合预训练,在多个下游的文档理解任务上取得了领先的结果. 本文分享自华为云社区<论文解读系列二十五:LayoutLM: 面向文 ...
- H-ui JQuery 给单选按纽赋值不生效
H-ui JQuery 给单选按纽赋值不生效 $("#sex-1").attr('checked',true) 原因,iradio-blue 样式的原因 把下面代码注释掉就可以了 ...
- 当谈论 React hook,我们究竟说的是什么?
这个标题很大,但是落点很小,只是我,一个开发者在学习和使用 hooks 中的一点感受和总结. React hook 的由来 React hook 的由来,其实也可以看作是前端技术不断演进的结果. 在 ...