反射是.net中的高级功能之一,利用反射可以实现许多以前看来匪夷所思的功能,下面是我看了《ProgrammingC#》(O'Reilly)之后对于反射的一点实践,本想直接做个应用程序来说明问题,但苦于工作繁忙并考虑到以简单为主,故先对反射发送(reflection emit)的使用做一些介绍。文章最后再给出一个实例。
下面的程序在运行时生成了一个Test.cs文件,并调用csc编译成Test.dll文件,然后利用Type.InvokeMember()方法调用其中的SayHello()方法,然后和原始方法对比一下性能。
usingSystem;
usingSystem.Diagnostics;
usingSystem.IO;
usingSystem.Reflection;
namespaceInvokeMember
{
///<summary>
///Class1 的摘要说明。
///</summary>
classClass1 {///<summary>
///应用程序的主入口点。
///</summary>
[STAThread]
staticvoidMain(string[] args)
{
//循环次数
constintiterations=100;
//计算所用时间
DateTime startTime=DateTime.Now;
for(inti=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=newReflectionTest();
//计算所用时间
startTime=DateTime.Now;
for(inti=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>
publicclassReflectionTest
{
//保存动态生成并编译的类的type对象
Type theType=null;
//保存动态生成类的实例
objecttheClass=null;
///<summary>
///供Client调用的方法
///</summary>
publicvoidDoOperation()
{
//未初始化
if(theType==null)
{
//初始化
GenerateCode();
}
//调用方法时的参数数组(此处为空)
object[] arguments=newobject[0];
//调用动态生成类的方法
theType.InvokeMember("SayHello",//要调用的方法名
BindingFlags.Default|BindingFlags.InvokeMethod,//Binding标志,具体参看msdn
null,//使用默认Binding对象
theClass,//在theClass实例上调用此方法
arguments//调用方法时的参数数组
);
}
///<summary>
///运行时生成代码
///</summary>
privatevoidGenerateCode()
{
//文件名
stringfileName="Test";
//打开文件,如果不存在,则创建
Stream s=File.Open(fileName+".cs",FileMode.Create);
//创建一个StreamWriter来写入数据
StreamWriter wrtr=newStreamWriter(s);
//写入动态创建类的源代码
wrtr.WriteLine("// 动态创建Test类");
//类名
stringclassName="TestClass";
wrtr.WriteLine("using System;");
wrtr.WriteLine("class {0}",className);
wrtr.WriteLine("{");
wrtr.WriteLine(" public void SayHello()");
wrtr.WriteLine(" {");
wrtr.WriteLine(" Console.WriteLine("Hello,World");");
wrtr.WriteLine(" }");
wrtr.WriteLine("}");
//关闭StreamWriter和文件
wrtr.Close();
s.Close();
//启动进程编译源文件
//指定参数
ProcessStartInfo psi=newProcessStartInfo();
//启动cmd.exe
psi.FileName="cmd.exe";
//cmd.exe的参数,/c-close,完成后关闭;后为参数,指定cmd.exe使用csc来编译刚才生成的源文件
stringcompileString="/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");
}
}
}