emit学习-helloworld(代码片段)

linybo linybo     2022-12-07     737

关键词:

之前看过Dapper(使用到了Emit), CYQ.Data(另一种思路,没有使用Emit)类的框架之后, 也想自己做一个小框架玩一下, 不过此时能力太过欠缺, 做不了Cyq.Data或者PDF.Net此类的框架, 所以开始了学习之路. 先制定一个能达到的小目标吧, 从Emit开始. 

可能很多人还不知道Emit是个什么鬼, 但是听说过EmitMapper的肯定有不少, Emit的概念, 我这里就不多说了, 可以看一下别人的博文(下面的链接里面就有)

一、使用场景

Emit的使用场景了,通常我们在下面几种情形时可以选择使用Emit来实现: 

     1.  运行中动态的创建类型、模块等,同时又需要提高效率(可以动态编译一次,然后就不用再处理了).

     2 .延迟绑定对象的使用。

     3 . 工具插件及IDE的开发等。 

     4.   ORM的实现。

     5.   减少反射的性能损失。

二、小示例

以下部分转载自 : http://www.cnblogs.com/gjhjoy/p/3627243.html (若侵权, 请与我联系, 删除此部分内容)

static void Main(string[] args)
        
            //1.构建程序集
            var asmName = new AssemblyName("Test");
            var asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);

            //2.创建模块
            var mdlBldr = asmBuilder.DefineDynamicModule("Elvinle", "Elvinle.exe");

            //3.定义类
            var typeBldr = mdlBldr.DefineType("Hello", TypeAttributes.Public);

            //4.定义类成员(方法,属性等等)
            //public void SayHello()
            var methodBldr = typeBldr.DefineMethod("SayHello", MethodAttributes.Public | MethodAttributes.Static, null, null);

            //5.构建方法体
            //获取il生成器 
            var il = methodBldr.GetILGenerator();
            il.Emit(OpCodes.Ldstr, "Hello, HelloWorld!");
            il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[]  typeof(string) ));
            il.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadLine"));
            il.Emit(OpCodes.Pop);//读入的值会被推送至evaluation stack,而本方法是没有返回值的,因此,需要将栈上的值抛弃 
            il.Emit(OpCodes.Ret);

            //调用CreateType来完成类型的创建
            var t = typeBldr.CreateType();
            //设置入口点为SayHello(), -- 相当于Main()
            asmBuilder.SetEntryPoint(t.GetMethod("SayHello"));
            asmBuilder.Save("Elvinle.exe");
        

结果如下:

技术图片

以下部分转载自 : http://www.cnblogs.com/Mervin/archive/2013/04/05/reflection-3.html  (若侵权, 请与我联系, 删除此部分内容)

使用Emit常用的几个类如下:

类名 用途
AssemblyBuilder  用来定义和创建动态的程序集
ConstructorBuilder  用来创建动态类的构造函数
CustomAttributeBuilder   用来创建用户自定义的特性
MethodBuilder        用来创建动态类的方法,也可创建构造函数,因为构造函数本身也是一个特殊的方法
ModuleBuilder    用来创建动态程序集中的模块
TypeBuilder    用来定义和创建动态类的新实例
DynamicMethod   用来创建可动态编译和执行的动态方法
ILGenerator         用来生成中间语言,即MSIL指令
OpCodes  提供 Microsoft 中间语言 (MSIL) 指令的字段表示形式

 

 

 

 

 

   

 

   

 

 

 

 

 

首先来看下使用Emit的一般步骤: 

    1. 创建一个程序集。 

    2. 在程序集内创建一个模块。 

    3. 在模块内创建动态类。 

    4. 为动态类添加动态方法,属性,事件,等等。 

    5. 生成相关的IL代码。

    6. 返回创建的类型或是持久化保存到硬盘中。

 

***************转摘:https://www.cnblogs.com/elvinle/p/6003332.html

vue组件通讯方式(代码片段)

props/$emit父组件<template><divclass="home"><HelloWorldmsg="WelcometoYourVue.jsApp"@showMsg="showMsg"/></div></template><script>importHelloWorldfrom\'@/components/HelloWorld.vue\'exportdefaultname:\'Home\',components:HelloWorld,,methods:showMsg(msg)console.log(... 查看详情

markdown学习(代码片段)

MarkDown学习二级标题三级标题四级标题二级标题HelloWorld!HelloWorld!HelloWorld!HelloWorld!引用hello分割线图片![截图](C:UsersPublicPicturesSamplePicturesDesert.jpg)超链接点击跳转到百度列表ACABC表格名字性别生日张三男1998.2.2代码代码 查看详情

markdown学习(代码片段)

Markdown学习标题三级标题四级标题字体HelloWorld!HelloWorld!HelloWorld!HelloWorld!引用时间不在于你拥有多少,而在于你怎样使用-时间刺客分割线图片超链接? 点击跳转到我的博客列表ABCABC表格姓名性别年龄张三男21李四女22王五男24... 查看详情

markdown学习(代码片段)

...###四级标题#####五级标题三级标题四级标题五级标题字体*helloworld***helloworld*****helloworld***~~helloworld~~helloworldhelloworldhelloworldhelloworld引用>引用效果演示引用效果演示分割线---***图片![图片名 查看详情

rabbitmq学习----helloworld简单模型(代码片段)

文章目录RabbitMQ学习(二)----HelloWorld简单模型开放rabbitMQ端口号5672发送者(1)创建连接工厂connectionFactory(2)创建与rabbitmq的连接connection(3)通过连接创建信道channel(4)在 查看详情

rabbitmq学习----helloworld简单模型(代码片段)

文章目录RabbitMQ学习(二)----HelloWorld简单模型开放rabbitMQ端口号5672发送者(1)创建连接工厂connectionFactory(2)创建与rabbitmq的连接connection(3)通过连接创建信道channel(4)在 查看详情

markdown学习(代码片段)

 Markdown学习标题三级标题四级标题 字体 Helloworld!Helloworld!Helloworld!Helloworld! 引用选择狂神说Java,走向人生巅峰 分割线 图片 超链接点击跳转到Green_Leaf博客 列表ABCABC 表格名字性别生日张三男1970.1... 查看详情

golang学习---快速helloworld(代码片段)

...展。来看看go的hello,packagemainimport"fmt"funcmain()fmt.Println("helloworld!")同样,也可以像java,还有python那样。可以运行这个文件gorunmain.g 查看详情

学习使用vuemixin(代码片段)

importservicefrom‘@/utils/request‘constmyMix=created()this.helloWorld()this.getTypeList(),methods:helloWorld()console.log(‘helloworld‘),asyncgetTypeList()constretdata=awaitthis.$api.audit.get 查看详情

flask学习笔记(一helloworld)(代码片段)

初始化fromflaskimportFlaskapp=Flask(__name__)当从此文件进入时__name__为__main__。Flask用这个参数确定程序的根目录,以便查找资源文件的位置。路由和视图@app.route('/')defindex():return'<h1>HelloWorld!</h1>' 查看详情

helloworld,本章学习qt的基本功能(代码片段)

HelloWorld本章学习Qt的基本功能例1,简单的窗口这个简单的小例子展示的是一个小窗口。但是我们可以在这个小窗口上面做很多事情,改变大小,最大化,最小化等,这需要很多代码才能实现。这在很多应用中很常见,没必要每... 查看详情

nodemcu学习笔记---编写第一个nodemcu程序“helloworld!“(代码片段)

NodeMCU学习笔记(2)—编写第一个NodeMCU程序"HelloWorld!"提示:作者使用ESP8266进行开发学习。文章目录前言一、主程序(初始化程序)二、程序下载三、查看输出信息四、总结前言    根据文章《NodeMCU... 查看详情

zynq之嵌入式学习----开篇实验helloworld(代码片段)

1ZYNQ嵌入式系统的开篇实验HelloWorld阅读本文需先学习:FPGA学习----Vivado软件使用1.1ZYNQ嵌入式系统开发流程创建Vivado工程使用IPIntegrator创建ProcessorSystem生成顶层HDL生成比特流,导出到SDK在SDK中创建应用工程板级验证开篇实验任务... 查看详情

springmvc学习基础笔记——helloworld(代码片段)

写在开头:本人是移动开发工程师,近段时间在学习后端知识,希望以后可以一方面扩充自己的技术栈,也可以从更广的维度思考问题。SpringMVC可以简单的理解为Mvc模式, 模型(Model),视图(... 查看详情

springmvc学习基础笔记——helloworld(代码片段)

写在开头:本人是移动开发工程师,近段时间在学习后端知识,希望以后可以一方面扩充自己的技术栈,也可以从更广的维度思考问题。SpringMVC可以简单的理解为Mvc模式, 模型(Model),视图(... 查看详情

helloworld(代码片段)

/***@authormghio*@date:2020-01-16*@version:1.0*@description:Java搬运工&终身学习者@微信公众号「mghio」*@sinceJDK1.8*/publicclassHelloWorldpublicstaticvoidmain(String[]args)System.out.println("HelloWorld~~~"); 查看详情

markdown的学习(代码片段)

...标题#+空格=一级标题##+空格=二级标题以此类推 字体HelloWorld一个星号中间是斜体HelloWorld两个星号中间是粗体HelloWorld三个星号中间是粗斜体HelloWorld两个波浪中间是删除线 引用引用别处的东西用>+空格  分割线三... 查看详情

vue3学习随便记10(代码片段)

深入组件自定义事件事件名规则和组件prop一样,即JS中camelCase,HTML中kebab-case。this.$emit('myEvent')<my-component@my-event="doSomething"></my-component>自定义事件在组件的emits选项上定义。如果在emits选项中定... 查看详情