zoukankan      html  css  js  c++  java
  • (转)反射发送实战(-)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(" public void SayHello()");
                wrtr.WriteLine(" {");

                wrtr.WriteLine(" Console.WriteLine("Hello,World");");
                wrtr.WriteLine(" }");
                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");
            }
        }
    }

  • 相关阅读:
    让你彻底明白什么叫游戏引擎(1)
    今后几年将有多于28部游戏电影面世
    Symbian系统体系结构
    让你彻底明白什么叫游戏引擎(2)
    网易程序笔试题
    [转贴]暴雪的霸王条款是否合理?
    CPU GPU设计工作原理《转》
    求伯君:向暴雪学习 金山不求一夜暴富
    我的职业规划
    网络游戏程序员新手入门 [转]
  • 原文地址:https://www.cnblogs.com/wanshutao/p/4148498.html
Copyright © 2011-2022 走看看