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 ...
随机推荐
- NoSQL数据库与关系数据库的比较
1.在原理方面 2.在数据规模方面 3.在数据库模式方面 4.查询效率方面: 5.在事务一致性方面: 6.在数据完整性方面: 7.在可扩展性方面: 8.在可用性方面 9.在标准化方面: 10.在技术支 ...
- flask的cookie和session会话保持
Cookie 获取请求cookie 通过请求对象中的cookies属性可以获取cookie. 实例: from flask import Flask, request @app.route(" ...
- 企业u盘禁止访问如何解锁
如果您遇到了U盘禁止访问的问题,可能是由于系统设置.安全策略或第三方工具导致的.以下是一些可能的解锁方法,具体的操作可能因具体情况而异: 管理员权限: 确保您有足够的管理员权限来解锁U盘.有时,系统管 ...
- 【Python】【OpenCV】视频帧和摄像头帧操作 and 窗口显示
一.读取写入视频文件 1 import cv2 2 3 # 创建一个视屏捕获对象 4 videoCapture = cv2.VideoCapture('AVI.avi') 5 6 # 获取视频的属性值 ...
- 丝丝入扣,毫不违和,AI一键换脸和微调,基于Rope-Ruby,2024最新整合包
AI换脸已经不是什么时新的技术了,从DeepFace到Facesweap,再到Roop.AI换脸技术中出现了一种名为"一键换脸"的方法,它不需要训练模型.这种方法利用了名为&quo ...
- Python——第五章:json模块
什么是json: json 模块是用于处理 JSON(JavaScript Object Notation)数据的模块,翻译过来叫js对象简谱.JSON是一种轻量级的数据交换格式,常用于将数据在不同语 ...
- 提取 PE文件 / 目标程序 的各种信息
前段时间项目需要实现对 Windows PE 文件版本信息的提取,如文件说明.文件版本.产品名称.版权.原始文件名等信息.获取这些信息在 Windows 下当然有一系列的 API 函数供调用,简单方便 ...
- vue部署项目报错导致空白页解决
在nginx上部署项目出现空白页并报错 解决方法: 在vue的vue.config.js文件中 改成:module.exports = {publicPath: './'}
- Unity3D学习笔记5——创建子Mesh
目录 1. 概述 2. 详论 2.1. 实现 2.2. 解析 3. 参考 1. 概述 在文章Unity3D学习笔记4--创建Mesh高级接口通过高级API的方式创建了一个Mesh,里面还提到了一个Su ...
- curl使用小记(一)
目录 1. 概述 2. 实例 2.1. 访问网页 2.2. 显示头信息 2.3. 保存网页 2.4. 下载图片 2.5. 用户代理设置 2.6. 代理设置 3. 参考 1. 概述 curl也就是com ...