Emit意在动态构建一个可以执行(当然也就可以反射)或者只可以反射的动态库。

个人认为在不得不使用反射的情况下,使用Emit会使得效率提升空间很大。亦或者动态插件模式的软件设计中会用到。

依然2%的废话和98%的代码:

 using System;
using System.Reflection;
using System.Reflection.Emit; namespace ReflectionTest
{
class Program
{
static void Main(string[] args)
{
//Emit
/*
Emit的知识隶属于反射的一部分,也是比较偏门的一部分。
在出现Dynamic和匿名类之后,它会有更小的用武之地,但仍然属于Reflection的知识范畴。
区别于“正常”的反射,Emit是动态的构建一个类,
比如,现在你没有Person.Dll,没有项目可以引用,没有可以反射的对象
那么你可能会想到Emit,它可以使你用代码构建出一个Person类,你甚至可以把动态构建的类保存成DLL,然后使用反射调用
虽然也是用C#去实现,但语法风格大不相同,强硬的理解,可以理解Emit暴漏给C#一些接口,让你去操作IL,然后生成动态库
在这次的blog中,我们的目的就是用代码构建出这个person类。OK,Let's start
*/
//STEP 1. Give him a name
var assemblyName = new AssemblyName("PersonMoudle"); //STEP 2. Build a assembly
var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName,
AssemblyBuilderAccess.RunAndSave); //STEP 3. Add a moudle
var moudle = assemblyBuilder.DefineDynamicModule("PersonMoudle", "PersonMoudle.dll"); //SETP 4. Add a Class
var typePart = moudle.DefineType("Person", TypeAttributes.Public); //SETP 5. Add a method for this Class
var methodPart = typePart.DefineMethod("SayHi", MethodAttributes.Public, null, null); //STEP 6. Imp the method
var il = methodPart.GetILGenerator();
il.EmitWriteLine("Hi! I'm SayHi method!");
il.Emit(OpCodes.Ret); typePart.CreateType();
assemblyBuilder.Save("PersonMoudle.dll"); //再比如,构建一个exe
var ad = AppDomain.CurrentDomain;
var am = new AssemblyName {Name = "TestEmit"};
var ab = ad.DefineDynamicAssembly(am, AssemblyBuilderAccess.Save);
var mb = ab.DefineDynamicModule("testmod", "输出一句话.exe");
var tb = mb.DefineType("TestEmit.Test", TypeAttributes.Public);
var metb = tb.DefineMethod("ConsoleWord", MethodAttributes.Public | MethodAttributes.Static, typeof (void),
null);
ab.SetEntryPoint(metb);
ILGenerator il1 = metb.GetILGenerator();
il1.EmitWriteLine("Hello World");
il1.EmitWriteLine("按任意键退出……");
il1.Emit(OpCodes.Call, typeof (Console).GetMethod("ReadKey",new Type[]{}));//指定无参数的重载。生产环境的代码中应该有更加严格判断,具体指定个某个方法请翻前篇的文章。
il1.Emit(OpCodes.Ret);
tb.CreateType();
ab.Save("输出一句话.exe");
Console.ReadKey();
}
}
}

我们可以看到,执行完这个之后,在Debug里会生成我们想要的PersonMoudle.dll和输出一句话.exe、反编译后的dll和exe的执行效果:

C#中反射的使用(How to use reflect in CSharp)(3)Emit的使用的更多相关文章

  1. JAVA中反射机制五(java.lang.reflect包)

    一.简介 java.lang.reflect包提供了用于获取类和对象的反射信息的类和接口.反射API允许对程序访问有关加载类的字段,方法和构造函数的信息进行编程访问.它允许在安全限制内使用反射的字段, ...

  2. JAVA中反射机制六(java.lang.reflect包)

    一.简介 java.lang.reflect包提供了用于获取类和对象的反射信息的类和接口.反射API允许对程序访问有关加载类的字段,方法和构造函数的信息进行编程访问.它允许在安全限制内使用反射的字段, ...

  3. Java中反射的三种常用方式

    Java中反射的三种常用方式 package com.xiaohao.test; public class Test{ public static void main(String[] args) t ...

  4. C#中反射接受的字符串需要满足的Backus-Naur Form语法

    MSDN的Specifying Fully Qualified Type Names指明了C#中反射接受的字符串需要满足如下的Backus-Naur Form语法. BNF grammar of fu ...

  5. .NET中反射机制的使用与分析

    .NET中反射机制的使用与分析 [日期:2008-06-30] 来源:  作者:志伟     .NET反射的定义:审查元数据并收集关于它的类型信息的能力. 元数据是一种二进制信息,用以对存储在公共语言 ...

  6. java中反射学习整理

    转载请注明:http://blog.csdn.net/j903829182/article/details/38405735 反射主要是指程序能够訪问.检測和改动它本身的状态或行为的一种能力. jav ...

  7. 在C++中反射调用.NET(二)

    反射调用返回复杂对象的.NET方法 定义数据接口 上一篇在C++中反射调用.NET(一)中,我们简单的介绍了如何使用C++/CLI并且初步使用了反射调用.NET程序集的简单方法,今天我们看看如何在C+ ...

  8. 在C++中反射调用.NET(一)

    为什么要在C++中调用.NET 一般情况下,我们常常会在.NET程序中调用C/C++的程序,使用P/Invoke方式进行调用,在编写代码代码的时候,首先要导入DLL文件,然后在根据C/C++的头文件编 ...

  9. 在C++中反射调用.NET(三)

    在.NET与C++之间传输集合数据 上一篇<在C++中反射调用.NET(二)>中,我们尝试了反射调用一个返回DTO对象的.NET方法,今天来看看如何在.NET与C++之间传输集合数据. 使 ...

  10. Java中反射的实现方式

    所谓反射,是指在运行时状态中,获取类中的属性和方法,以及调用其中的方法的一种机制.这种机制的作用在于获取运行时才知道的类(Class)及其中的属性(Field).方法(Method)以及调用其中的方法 ...

随机推荐

  1. IOS cocos2d笔记1

    结点添加.删除.获取1.结点:CCNode * childNode = [CCNode node]; 2.加入结点[myNode addChild:childNode z:0 tag:123];//z ...

  2. Android手动画柱状图的例子

    效果图如上,网上看到的例子,谨以此文记录一下,以后用到的地方再来翻翻. 核心技术是用Canvas和Paint画长方形. 源码地址:http://download.csdn.net/detail/abc ...

  3. 【大数模板】C++大数类 大数模板

    分别使用C++中的运算符重载的方法来实现大数之间的数学运算,包括加法.减法.乘法.除法.n次方.取模.大小比较.赋值以及输入流.输出流的重载. 感觉很麻烦... [代码] #include<io ...

  4. .NET之美——C#中的委托和事件(续)

    C#中的委托和事件(续) 引言 如果你看过了 C#中的委托和事件 一文,我想你对委托和事件已经有了一个基本的认识.但那些远不是委托和事件的全部内容,还有很多的地方没有涉及.本文将讨论委托和事件一些更为 ...

  5. ylbtech-Model-Account(通用账户模块设计)

    ylbtech-DatabaseDesgin:ylbtech-Model-Account(通用账户模块设计) ylbtech-Model-Account(通用账户模块设计) 1.A,数据库关系图(Da ...

  6. Mybatis拦截器介绍

    拦截器的一个作用就是我们可以拦截某些方法的调用,我们可以选择在这些被拦截的方法执行前后加上某些逻辑,也可以在执行这些被拦截的方法时执行自己的逻辑而不再执行被拦截的方法.Mybatis拦截器设计的一个初 ...

  7. Delphi TRichEdit加载word内容

    procedure TForm1.btn6Click(Sender: TObject);var WordApp: Variant; //声明一个word对象beginWordApp := Create ...

  8. 总结:ADO.NET在开发中的部分使用方法和技巧

    如何使用 SqlDataAdapter 来检索多个行 以下代码阐明了如何使用 SqlDataAdapter 对象发出可生成 DataSet 或 DataTable 的命令.它从 SQL Server ...

  9. ARM处理机模式--内部寄存器

    处理器模式 用户模式(user)简称usr 快速中断模式(FIQ)简称fiq 外部中断模式(IRQ)简称irq 特权模式(supervisor)简称sve 数据访问终止模式(abort)简称abt 未 ...

  10. 修改 myeclipse8.5 servlet 模板

    在myeclipse8.5的安装目录下找到 \Common\plugins下的com.genuitec.eclipse.wizards_8.5.0.zmyeclipse75020090612.jar ...