emit学习-helloworld

Sniper_ZL Sniper_ZL     2022-08-10     405

关键词:

之前看过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. 返回创建的类型或是持久化保存到硬盘中。

三、指令明细, 有点类似 汇编 

由于之前电脑vs安装的是英文版的, 对于一些OpCodes指令, 有一些看的不是很懂, 所以附上一个中文版的吧

地址:http://files.cnblogs.com/files/elvinle/OpCodes.rar 

.net动态代理-emit,aop实现

动态代理实现原理:  通过动态基础目标类,重写目标虚方法,.net中实现手段-il  Emit.Proxy项目源码,https://github.com/1448376744/Emit.Proxy  以下是基于Emit.Proxy实现的DemoclassProgramstaticvoidMain(string[]args)Console.WriteLine("HelloWorld!");var 查看详情

触发与监听事件emit

<scriptsetup>importCompfrom'./Comp.vue'importreffrom'vue'constmsg=ref('HelloWorld!')consthandleUpdate=(value,value2)=>msg.value=value</script>< 查看详情

触发与监听事件emit

<scriptsetup>importCompfrom'./Comp.vue'importreffrom'vue'constmsg=ref('HelloWorld!')consthandleUpdate=(value,value2)=>msg.value=value</script>< 查看详情

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(... 查看详情

emit学习-il-值类型和引用类型(补)

...活嘛,所以我把生活,工作分的比较开.这几天不是很忙,在学习工作技能的同时,发点博文,也算是做一个学习笔记上篇中,贴出的地址里面那位哥,也有一篇值类型和引用类型的文章来源:http://www.cnblogs.com/yingql/archive/2009/03/23/1420026.html... 查看详情

javascript学习笔记helloworld

<html><body><scriptlanguage="JavaScript">alert("Helloworld");</script></body></html>  查看详情

spring学习--helloworld

...ing框架图:  下面我们开始Spring第一个经典项目:HelloWorld普通模式的Helloworld:1packagecom.itdjx.spring. 查看详情

c语言学习笔记:helloworld!

1#include<stdio.h>23voidmain()4{5printf("HelloWorld! ");6}几乎学习任何语言接触到的第一个语言都是HelloWorld!先是头文件.(stdio.h是standardinputandoutput的缩写)然后是主函数,主函数名称一定是main.主函数内部调用printf()函数输出字符串:HelloWorld... 查看详情

rabbitmq学习——helloworld

publicclassSend{ publicstaticvoidmain(String[]args)throwsException{ ConnectionFactoryfactory=newConnectionFactory(); factory.setHost("localhost"); Connectionconnection=factory.newConnection(); Ch 查看详情

moos学习笔记2——helloworld回调

MOOS学习笔记2——HelloWorld回调例程#include"MOOS/libMOOS/Comms/MOOSAsyncCommClient.h"boolOnConnect(void*pParam)CMOOSCommClient*pC=reinterpret_cast<CMOOSCommClient*>(pParam);pC->Register("Greeting",0.0 查看详情

helloworld!

...天开始第一天的学习。C++的语法元素:  一、简单的“HelloWorld”程序。    1 #include<iostream>    2 usingnamespacestd;    3 intmain()    4     5&nb 查看详情

moos学习笔记1——helloworld

MOOS学习笔记1——HelloWorld例程/**@功能:通讯客户端的最简单程序,向MOOSDB发送名为"Greeting"*数据"Hello",并向MOOSDB订阅该信息,接收信息后显示*出来*//**@功能:插入通讯类头文件*@介绍:MOOSAsyncCommClient与DB连接以后启动两个不同步... 查看详情

markdown操作学习

#MarkDown学习##二级标题###三级标题####四级标题##字体HelloWorld!!HelloWorld!!HelloWorld!!HelloWorld!!##引用>这是引用的话##分割线---***三个*或者三个-##图片![tutu](C:\\Users\\Administrator\\Documents\\TencentFiles\\523480514\\Image\\Gr 查看详情

学习springmvc——从helloworld开始

前言:  虽然从学java的第一个程序——helloworld至今,已经有好几个年头了。当时自己找资料,看视频,学习了java的输入输出流,多线程,网络编程等等,而三大框架(Struts、Hibernate、Spring)基本只是开了个头就出来实... 查看详情

springmvc学习笔记一helloworld

SpringMVC学习笔记一HelloWorldSpringMVC的使用可以按照以下步骤进行(使用Eclipse):加入JAR包在web.xml中配置DispatcherServlet加入SpringMVC的配置文件编写处理请求的处理器,并添加对应注解编写视图下面按照国际惯例先来一个HelloWorld,在... 查看详情

springboot学习随笔:简单的helloworld

接上章搭建好springboot环境后,开始开发入门级HelloWorld一.构建简单的springboot项目1.新建项目,选择Spring/SpringStarterProject2.Next此处目前阶段只选择web即可 3.Finish,生成项目(下图为参考图,非本次新建的HelloWorld项目图,除了项... 查看详情

markdown学习(代码片段)

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

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

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