(转)反射发送实战(-)InvokeMember
反射是.net中的高级功能之一,利用反射可以实现许多以前看来匪夷所思的功能,下面是我看了《Programming C#》(O'Reilly)之后对于反射的一点实践,本想直接做个应用程序来说明问题,但苦于工作繁忙并考虑到以简单为主,故先对反射发送(reflection emit)的使用做一些介绍。文章最后再给出一个实例。
下面的程序在运行时生成了一个Test.cs文件,并调用csc编译成Test.dll文件,然后利用Type.InvokeMember()方法调用其中的SayHello()方法,然后和原始方法对比一下性能。
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
namespace InvokeMember
{
/// <summary>
/// Class1 的摘要说明。
/// </summary>
class Class1 { /// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
//循环次数
const int iterations = 100;
//计算所用时间
DateTime startTime = DateTime.Now;
for(int i = 0;i< iterations;i++) { //对照方法
Console.WriteLine("Hello,World");
}
TimeSpan elASPed = DateTime.Now - startTime;
Console.WriteLine("Looping Elapsed milliseconds:" + elasped.TotalMilliseconds + "for {0} iterations",iterations);
//使用反射发送
ReflectionTest t = new ReflectionTest();
//计算所用时间
startTime = DateTime.Now;
for(int i = 0;i < iterations;i++)
{
t.DoOperation();
}
elasped = DateTime.Now - startTime;
Console.WriteLine("Looping Elapsed milliseconds:" + elasped.TotalMilliseconds + "for {0} iterations",iterations);
Console.ReadLine();
}
}
/// <summary>
/// Reflection 的摘要说明。
/// </summary>
public class ReflectionTest
{
//保存动态生成并编译的类的type对象
Type theType = null;
//保存动态生成类的实例
object theClass = null;
/// <summary>
/// 供Client调用的方法
/// </summary>
public void DoOperation()
{
//未初始化
if(theType == null)
{
//初始化
GenerateCode();
}
//调用方法时的参数数组(此处为空)
object[] arguments = new object[0];
//调用动态生成类的方法
theType.InvokeMember("SayHello",//要调用的方法名
BindingFlags.Default|BindingFlags.InvokeMethod,//Binding标志,具体参看msdn
null,//使用默认Binding对象
theClass,//在theClass实例上调用此方法
arguments//调用方法时的参数数组
);
}
/// <summary>
/// 运行时生成代码
/// </summary>
private void GenerateCode()
{
//文件名
string fileName = "Test";
//打开文件,如果不存在,则创建
Stream s = File.Open(fileName + ".cs",FileMode.Create);
//创建一个StreamWriter来写入数据
StreamWriter wrtr = new StreamWriter(s);
//写入动态创建类的源代码
wrtr.WriteLine("// 动态创建Test类");
//类名
string className = "TestClass";
wrtr.WriteLine("using System;");
wrtr.WriteLine("class {0}",className);
wrtr.WriteLine("{");
wrtr.WriteLine("\tpublic void SayHello()");
wrtr.WriteLine("\t{");
wrtr.WriteLine("\t\tConsole.WriteLine(\"Hello,World\");");
wrtr.WriteLine("\t}");
wrtr.WriteLine("}");
//关闭StreamWriter和文件
wrtr.Close();
s.Close();
//启动进程编译源文件
//指定参数
ProcessStartInfo psi = new ProcessStartInfo();
//启动cmd.exe
psi.FileName = "cmd.exe";
//cmd.exe的参数,/c-close,完成后关闭;后为参数,指定cmd.exe使用csc来编译刚才生成的源文件
string compileString = "/c C:\\WINNT\\Microsoft.NET\\Framework\\v1.1.4322\\csc.exe /optimize+ /target:library {0}.cs";
psi.Arguments = String.Format(compileString,fileName);
//运行时的风格-最小化
psi.Windowstyle = ProcessWindowstyle.Minimized;
//启动进程
Process proc = Process.Start(psi);
//指定当前在此进程退出前等待
proc.WaitForExit();
//从编译好的dll文件load一个Assembly
Assembly a = Assembly.LoadFrom(fileName + ".dll");
//创建类的实例
theClass = a.CreateInstance(className);
//取得此类实例的类型
theType = a.GetType(className);
//删除源文件
//File.Delete(flieName + ".cs");
}
}
}
(转)反射发送实战(-)InvokeMember的更多相关文章
- scrapy——4 —反爬措施—logging—重要参数—POST请求发送实战
scrapy——4 常用的反爬虫策略有哪些 怎样使用logging设置 Resquest/Response重要参数有哪些 Scrapy怎么发送POST请求 动态的设置User-Agent(随即切换Us ...
- Windows下底层数据包发送实战
1.简介 所谓“底层数据包”指的是在“运行”于数据链路层的数据包,简单的说就是“以太网帧”,而我们常用的Socket只能发送“运行”在传输层的TCP.UDP等包,这些传输层数据包已经能满足绝大部分需求 ...
- Java反射机制实战——字段篇
首先,我们来认识几个类. Class(java.lang.Class) Class对象是一个特殊对象,每一个类都有一个Class对象,用来创建该类的“常规”对象.可以通过对象的getClass()方法 ...
- 实战Java的反射机制
众所周知,Java要调用某个对象的方法首先需要对象实例化后才能调用. 而实例化对象常见的就是new执行和spring(DI)的依赖注入了. Spring的DI其实就是以反射作为最基础的技术手段. 一. ...
- C#基础系列 - 反射基础
反射用于在程序运行过程中,获取类里面的信息或发现程序集并运行的一个过程.通过反射可以获得.dll和.exe后缀的程序集里面的信息.使用反射可以看到一个程序集内部的类,接口,字段,属性,方法,特性等信息 ...
- Kotlin反射实践操作详解
继续对反射进行实战. 获取构造方法: 先定义一个主构造方法,2个次构造方法,接下来咱们用反射来获取一下构造方法: 其结果: [fun <init>(kotlin.Int, kotlin.S ...
- Java高级篇反射和注解
反射是什么? 反射的作用?能带来什么好处? 反射的使用? 注解的使用? 注解和反射配合实战...
- C#程序实现动态调用DLL的研究(转)
摘 要:在<csdn开发高手>2004年第03期中的<化功大法——将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资 ...
- C#程序实现动态调用DLL的研究[转]
摘 要: 在< csdn 开发高手> 2004 年第 03 期中的<化功大法——将 DLL 嵌入 EXE >一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在 ...
随机推荐
- Qt在VS2013或Qt Creator 中的控制台输出方式设置
首先值得注意的是:在写程序的时候,项目保存路径不要涉及到中文,否则容易出错! 一.Qt在VS2013中的控制台输出方式: 注意:这里是而不是Qt Application. 然后直接点击finish即可 ...
- 转自:http://blog.sina.com.cn/s/blog_86e874d30101e3d8.html(谢谢原文作者),Win7下安装CentOS 6.5双系统
经过一下午的折腾,终于在64位的Windows 7上面成功安装了CentOS 6.5(64bit)系统,中途因为硬盘分区的问题失败了一次.下面是安装过程: 在安装过程中借助了这篇文章的内容:http: ...
- nginx_笔记分享_php-fpm详解
参考 http://syre.blogbus.com/logs/20092011.htmlhttp://www.mike.org.cn/articles/what-is-cgi-fastcgi-php ...
- 获取元素位置信息:getBoundingClientRect
一个神奇的方法. 一.历史 偷个懒,上个传送门:http://www.cnblogs.com/2050/archive/2012/02/01/2335211.html 二.介绍 DOM元素方法,返回一 ...
- Spring碎点知识
1.依赖注入:不仅可以为Bean注入普通的属性值,还可以注入其他Bean的作用.通过配置文件组织在一起,这里的Bean是Java对象 说明:关于依赖注入与控制反转的这两个名字,表达的都是同一个意思,只 ...
- 电脑远程控制手机2—webkey
远程控制神器,这个是真真切切试验成功了.我用的手机是OPPOR817和华为A199. 网上去下载webkey,http://soft.shouji.com.cn/down/23169.html 然后安 ...
- dos命令弹出对话框---Msg命令详解
标签: dos批处理对话框 2015-11-12 17:20 497人阅读 评论(0) 收藏 举报 脚本(30) 版权声明:本文为博主原创文章,未经博主允许不得转载. dos命令弹出对话框---Ms ...
- JavaScript 实现数组的foreach
Array.prototype.forEach = function (action) { for (var i = 0; i < this.length; i++) { action(this ...
- http协议的各个版本及区别
这个东西在一篇博文上面看见的,谢谢原博主提供!又学习了...
- MFC之CToolTipCtrl按钮提示(消息捕获和消息传递)
记得以前写对话框时,按钮直接有一个tips属性,可以添加默认值,不记得是C#还是啥了,今天忽然想给几个按钮添加提示信息,就捣鼓了一下. 头文件中创建CToolTipCtrl变量,然后在初始化时激活使用 ...