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 ...
随机推荐
- Codeforces Round 906 (Div. 2)A-E1
A. Doremy's Paint 3 记数组中数的种类数为\(k\),当\(k=1\)时,答案为\(yes\):当\(k=2\)时,记两个种类的数的个数差为\(d\),当\(d≤1\)时,答案为\( ...
- 华企盾DSC苹果电脑右键菜单不显示问题
1.检查认证的用户是否给了对应的权限(如:手动加密.手动解密.申请解密) 2.系统偏好设置--键盘--快捷键中开通的权限是否有勾选 3.系统服务中允许的菜单数超出了最大值
- svn、git服务器配置进程方式网关不生效常见处理方法
过华企盾DSC防泄密系统配置svn或者git服务器的时候,网关不生效如何解决? 1.先在cmd中运行一下命令netstat -ano|findstr "8080" 找到svn.gi ...
- VS2022 安装 .NET Framework 4.0 和 .NET Framework 4.5 的方法
解决方法 1.下载.NET Framework框架 .NET Framework 4.5.2 .NET Framework 4.5.1 .NET Framework 4.5 .NET Framewor ...
- springboot整合hibernate(非JPA)(二)
springboot整合hibernate(非JPA)(二) springboot整合hibernate,非jpa,若是jpa就简单了,但是公司项目只有hibernate,并要求支持多数据库,因此记录 ...
- K8S系列一:概念入门
K8S系列一:概念入门 写在前面 本文组织方式: K8S的架构.作用和目的.需要首先对K8S整体有所了解. K8S是什么? 为什么是K8S? K8S怎么做? K8S的重要概念,即K8S的API对象.要 ...
- 实时数据流无忧:用 SpringBoot 和 SSE 打造动态前端更新的终极指南
用 SpringBoot 和 SSE 打造动态前端更新的终极指南 你知道什么是开发者的梦魇吗?慢!慢!慢!在一个需要实时数据更新的应用中,如果数据像乌龟一样慢吞吞地爬行,那用户体验就会像坐过山车一样直 ...
- node.js 命令必须加 npx 才能执行
问题描述 在 Windows 上搭建 Hexo 环境,已经从官网下载安装 node-v18.18.2-x64.msi,并且通过 npm 命令成功安装 hexo. PowerShell 中,直接执行 h ...
- 全国网络安全行业职业技能大赛云南省选拔赛 Misc 部分WP
word_sercet 题目 我的解答: 加密文档,010打开图片发现密码 VVV_123.com 解压打开得到flag(注:flag原本是隐藏的,但我之前设置过隐藏文字自动显示,因此这里直接可以看到 ...
- 火山引擎 DataLeap 构建Data Catalog系统的实践(三):关键技术与总结
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 关键技术 构建一个好的Data Catalog系统,需要考虑的核心产品设计和技术设计有很多.篇幅所限,本文只概要介 ...