C#中反射的使用(How to use reflect in CSharp)(3)Emit的使用
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的使用的更多相关文章
- JAVA中反射机制五(java.lang.reflect包)
一.简介 java.lang.reflect包提供了用于获取类和对象的反射信息的类和接口.反射API允许对程序访问有关加载类的字段,方法和构造函数的信息进行编程访问.它允许在安全限制内使用反射的字段, ...
- JAVA中反射机制六(java.lang.reflect包)
一.简介 java.lang.reflect包提供了用于获取类和对象的反射信息的类和接口.反射API允许对程序访问有关加载类的字段,方法和构造函数的信息进行编程访问.它允许在安全限制内使用反射的字段, ...
- Java中反射的三种常用方式
Java中反射的三种常用方式 package com.xiaohao.test; public class Test{ public static void main(String[] args) t ...
- C#中反射接受的字符串需要满足的Backus-Naur Form语法
MSDN的Specifying Fully Qualified Type Names指明了C#中反射接受的字符串需要满足如下的Backus-Naur Form语法. BNF grammar of fu ...
- .NET中反射机制的使用与分析
.NET中反射机制的使用与分析 [日期:2008-06-30] 来源: 作者:志伟 .NET反射的定义:审查元数据并收集关于它的类型信息的能力. 元数据是一种二进制信息,用以对存储在公共语言 ...
- java中反射学习整理
转载请注明:http://blog.csdn.net/j903829182/article/details/38405735 反射主要是指程序能够訪问.检測和改动它本身的状态或行为的一种能力. jav ...
- 在C++中反射调用.NET(二)
反射调用返回复杂对象的.NET方法 定义数据接口 上一篇在C++中反射调用.NET(一)中,我们简单的介绍了如何使用C++/CLI并且初步使用了反射调用.NET程序集的简单方法,今天我们看看如何在C+ ...
- 在C++中反射调用.NET(一)
为什么要在C++中调用.NET 一般情况下,我们常常会在.NET程序中调用C/C++的程序,使用P/Invoke方式进行调用,在编写代码代码的时候,首先要导入DLL文件,然后在根据C/C++的头文件编 ...
- 在C++中反射调用.NET(三)
在.NET与C++之间传输集合数据 上一篇<在C++中反射调用.NET(二)>中,我们尝试了反射调用一个返回DTO对象的.NET方法,今天来看看如何在.NET与C++之间传输集合数据. 使 ...
- Java中反射的实现方式
所谓反射,是指在运行时状态中,获取类中的属性和方法,以及调用其中的方法的一种机制.这种机制的作用在于获取运行时才知道的类(Class)及其中的属性(Field).方法(Method)以及调用其中的方法 ...
随机推荐
- Android+Eclipse+Java:在“正在启动 CrazySnake”期间发生了内部错误, java.lang.NullPointerException
删除工作空间下的.metadata 文件夹 重启 Eclipse 清理工作空间
- 修改数据库中group_concat的返回结果的长度限制
修改数据库中group_concat的返回结果的长度限制 我们可以使用Mysql的客户端管理工具,Sqlyog 新建一个查询编辑器 显示 SHOW VARIABLES LIKE "grou ...
- 【转】Android之NetworkOnMainThreadException异常
看名字就应该知道,是网络请求在MainThread中产生的异常 先来看一下官网的解释: Class Overview The exception that is thrown when an appl ...
- [shell]通过ping检测整个网段IP的网络状态脚本
要实现Ping一个网段的所有IP,并检测网络连接状态是否正常,很多方法都可以实现,下面简单介绍两种,如下:脚本1#!/bin/sh# Ping网段所有IP# 2012/02/05ip=1 #通过修改初 ...
- 2014年acm亚洲区域赛·鞍山站
今天北京赛站的比赛也结束了···看了一天的直播之后意识到鞍山站的比赛都过去了一个多月了···这一个月比较萎靡···整天都在睡觉写报告画工图中度过··· 鞍山比哈尔滨还是暖和很多的···就是山上有奇怪的 ...
- memcache 分布式,算法实现
memcached 虽然称为 “ 分布式 ” 缓存服务器,但服务器端并没有 “ 分布式 ” 功能.每个服务器都是完全独立和隔离的服务. memcached 的分布式,则是完全由客户端程序库实现的. 这 ...
- delphi 设置表格样式。
//设置表格样式 wordDoc.Tables.Item(1).Borders.Item(Word.WdBorderType.wdBorderLeft).LineStyle = Word.WdLine ...
- 【Android】如何使用安卓的logcat『整理』
logcat是Android中一个命令行工具,可以用于得到程序的log信息.开发调试和测试定位bug都挺有用哒 有两种方式可以达到查看log的目的. 一 Eclipse集成DDMS插件 1 安装ecl ...
- Web自动化框架之五一套完整demo的点点滴滴(excel功能案例参数化+业务功能分层设计+mysql数据存储封装+截图+日志+测试报告+对接缺陷管理系统+自动编译部署环境+自动验证false、error案例)
标题很大,想说的很多,不知道从那开始~~直接步入正题吧 个人也是由于公司的人员的现状和项目的特殊情况,今年年中后开始折腾web自动化这块:整这个原因很简单,就是想能让自己偷点懒.也让减轻一点同事的苦力 ...
- <转>DNS服务系列之二:DNS区域传送漏洞的安全案例
DNS区域传送(DNS zone transfer)指的是一台备用服务器使用来自主服务器的数据刷新自己的域(zone)数据库.这为运行中的DNS服务提供了一定的冗余度,其目的是为了防止主的域名服务器因 ...