基础才是重中之重~Emit动态构建方法(参数和返回值)
对于Emit我们知道它的可以动态构建程序集,类型,方法,属性等,或者说只要手动使用C#创建的东西使用Emit也都可以动态创建它们,Emit由于它的特别之处,所以在很多领域得到了广泛的应用,像最近比较火的AOP技术,它最核心的功能就是方法拦截了,我们使用Emit也是可以实现方法拦截功能的,详细可以看大叔这篇文章《Lind.DDD.Aspects通过Plugins实现方法的动态拦截~Lind里的AOP》。
有参数,没有返回值的方法构建与调用
[TestMethod] public void BulidMethod() { //得到当前的应用程序域 AppDomain appDm = AppDomain.CurrentDomain; //初始化AssemblyName的一个实例 AssemblyName an = new AssemblyName(); //设置程序集的名称 an.Name = "EmitLind"; //动态的在当前应用程序域创建一个应用程序集 AssemblyBuilder ab = appDm.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run); //动态在程序集内创建一个模块 ModuleBuilder mb = ab.DefineDynamicModule("EmitLind"); //动态的在模块内创建一个类 TypeBuilder tb = mb.DefineType("HelloEmit", TypeAttributes.Public | TypeAttributes.Class); //动态的为类里创建一个方法 MethodBuilder mdb = tb.DefineMethod("HelloWord", MethodAttributes.Public, null, new Type[] { typeof(string) }); //得到该方法的ILGenerator ILGenerator ilG = mdb.GetILGenerator(); ilG.Emit(OpCodes.Ldstr, "Hello:{0}"); //加载传入方法的参数到堆栈 ilG.Emit(OpCodes.Ldarg_1); //调用Console.WriteLine方法,输出传入的字符 ilG.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string), typeof(string) })); ilG.Emit(OpCodes.Ret); //创建类的Type对象 Type tp = tb.CreateType(); //实例化一个类 object ob = Activator.CreateInstance(tp); //得到类中的方法,通过Invoke来触发方法的调用.. MethodInfo mdi = tp.GetMethod("HelloWord"); mdi.Invoke(ob, new object[] { "Hello Lind" }); }
有参数,同时有返回值的方法构建与调用
public void BulidMethodRet() { //得到当前的应用程序域 AppDomain appDm = AppDomain.CurrentDomain; //初始化AssemblyName的一个实例 AssemblyName an = new AssemblyName(); //设置程序集的名称 an.Name = "EmitLind"; //动态的在当前应用程序域创建一个应用程序集 AssemblyBuilder ab = appDm.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run); //动态在程序集内创建一个模块 ModuleBuilder mb = ab.DefineDynamicModule("EmitLind"); //动态的在模块内创建一个类 TypeBuilder tb = mb.DefineType("HelloEmit", TypeAttributes.Public | TypeAttributes.Class); //动态的为类里创建一个方法 MethodBuilder mdb = tb.DefineMethod( "HelloWorldReturn", MethodAttributes.Public, typeof(string), new Type[] { typeof(string), typeof(string) }); //得到该方法的ILGenerator ILGenerator ilG = mdb.GetILGenerator(); ilG.Emit(OpCodes.Ldstr, "你好:{0}-{1}"); //加载传入方法的参数到堆栈 ilG.Emit(OpCodes.Ldarg_1); ilG.Emit(OpCodes.Ldarg_2); //调用Console.WriteLine方法,输出传入的字符 ilG.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string), typeof(string) ,typeof(string)})); // ilG.Emit(OpCodes.Pop);//加这个就有问题了 //返回值部分 LocalBuilder local = ilG.DeclareLocal(typeof(string)); ilG.Emit(OpCodes.Ldstr, "Return Value:{0}"); ilG.Emit(OpCodes.Ldarg_1); ilG.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(string) })); ilG.Emit(OpCodes.Stloc_0, local); ilG.Emit(OpCodes.Ldloc_0, local); ilG.Emit(OpCodes.Ret); //创建类的Type对象 Type tp = tb.CreateType(); //实例化一个类 object ob = Activator.CreateInstance(tp); //得到类中的方法,通过Invoke来触发方法的调用.. MethodInfo mdi = tp.GetMethod("HelloWorldReturn"); mdi.Invoke(ob, new object[] { "Hello Lind","OK" }); }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)
2015-12-07 Lind.DDD~实体属性变更追踪器的实现
2012-12-07 爱上MVC3系列~同步与异步提交,在过滤器里如何进行重定向~续