分享

【经典实例】利用C#反射动态编译代码,创建类的实例,并调用其成员

 goodwangLib 2014-01-01
[c-sharp] view plaincopy
  1. using System;  
  2. using System.Diagnostics;  
  3. using System.IO;  
  4. using System.Reflection;  
  5.   
  6. namespace InvokeMember  
  7. {  
  8.     ///   
  9.     /// Class1 的摘要说明。  
  10.     ///   
  11.     class Class1 { ///   
  12.         /// 应用程序的主入口点。  
  13.         ///   
  14.         [STAThread]  
  15.         static void Main(string[] args)  
  16.         {  
  17.             //循环次数  
  18.             const int iterations = 100;  
  19.             //计算所用时间  
  20.             DateTime startTime = DateTime.Now;  
  21.             for(int i = 0;i< iterations;i++) { //对照方法  
  22.                 Console.WriteLine("Hello,World");  
  23.             }  
  24.             TimeSpan elasped = DateTime.Now - startTime;  
  25.             Console.WriteLine("Looping Elapsed milliseconds:" + elasped.TotalMilliseconds + "for {0} iterations",iterations);  
  26.               
  27.             //使用反射发送  
  28.             ReflectionTest t = new ReflectionTest();  
  29.             //计算所用时间  
  30.             startTime = DateTime.Now;  
  31.             for(int i = 0;i < iterations;i++)  
  32.             {  
  33.                 t.DoOperation();  
  34.             }  
  35.               
  36.             elasped = DateTime.Now - startTime;  
  37.   
  38.             Console.WriteLine("Looping Elapsed milliseconds:" + elasped.TotalMilliseconds + "for {0} iterations",iterations);  
  39.             Console.ReadLine();  
  40.         }  
  41.     }  
  42.   
  43.     ///   
  44.     /// Reflection 的摘要说明。  
  45.     ///   
  46.     public class ReflectionTest  
  47.     {  
  48.         //保存动态生成并编译的类的type对象  
  49.         Type theType = null;  
  50.         //保存动态生成类的实例  
  51.         object theClass = null;  
  52.   
  53.         ///   
  54.         /// 供Client调用的方法  
  55.         ///   
  56.         public void DoOperation()  
  57.         {  
  58.             //未初始化  
  59.             if(theType == null)  
  60.             {  
  61.                 //初始化  
  62.                 GenerateCode();  
  63.             }  
  64.             //调用方法时的参数数组(此处为空)  
  65.             object[] arguments = new object[0];  
  66.             //调用动态生成类的方法  
  67.             theType.InvokeMember("SayHello",//要调用的方法名  
  68.                 BindingFlags.Default|BindingFlags.InvokeMethod,//Binding标志,具体参看msdn  
  69.                 null,//使用默认Binding对象  
  70.                 theClass,//在theClass实例上调用此方法  
  71.                 arguments//调用方法时的参数数组  
  72.                 );  
  73.         }  
  74.   
  75.         ///   
  76.         /// 运行时生成代码  
  77.         ///   
  78.         private void GenerateCode()  
  79.         {  
  80.             //文件名  
  81.             string fileName = "Test";  
  82.             //打开文件,如果不存在,则创建  
  83.             Stream s = File.Open(fileName + ".cs",FileMode.Create);  
  84.             //创建一个StreamWriter来写入数据  
  85.             StreamWriter wrtr = new StreamWriter(s);  
  86.             //写入动态创建类的源代码  
  87.             wrtr.WriteLine("// 动态创建Test类");  
  88.   
  89.             //类名  
  90.             string className = "TestClass";  
  91.             wrtr.WriteLine("using System;");  
  92.             wrtr.WriteLine("class {0}",className);  
  93.             wrtr.WriteLine("{");  
  94.   
  95.             wrtr.WriteLine("/tpublic void SayHello()");  
  96.             wrtr.WriteLine("/t{");  
  97.   
  98.             wrtr.WriteLine("/t/tConsole.WriteLine(/"Hello,World/");");  
  99.             wrtr.WriteLine("/t}");  
  100.             wrtr.WriteLine("}");  
  101.   
  102.             //关闭StreamWriter和文件  
  103.             wrtr.Close();  
  104.             s.Close();  
  105.   
  106.             //启动进程编译源文件  
  107.             //指定参数  
  108.             ProcessStartInfo psi = new ProcessStartInfo();  
  109.             //启动cmd.exe  
  110.             psi.FileName = "cmd.exe";  
  111.             //cmd.exe的参数,/c-close,完成后关闭;后为参数,指定cmd.exe使用csc来编译刚才生成的源文件  
  112.             string compileString = "/c C://WINNT//Microsoft.NET//Framework//v1.1.4322//csc.exe /optimize+ /target:library {0}.cs";  
  113.             psi.Arguments = String.Format(compileString,fileName);  
  114.             //运行时的风格-最小化  
  115.             psi.WindowStyle = ProcessWindowStyle.Minimized;  
  116.           
  117.             //启动进程  
  118.             Process proc = Process.Start(psi);  
  119.             //指定当前在此进程退出前等待  
  120.             proc.WaitForExit();  
  121.   
  122.             //从编译好的dll文件load一个Assembly  
  123.             Assembly a = Assembly.LoadFrom(fileName + ".dll");  
  124.   
  125.             //创建类的实例  
  126.             theClass = a.CreateInstance(className);  
  127.             //取得此类实例的类型  
  128.             theType = a.GetType(className);  
  129.             //删除源文件  
  130.             //File.Delete(flieName + ".cs");  
  131.         }  
  132.     }  
  133. }  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多