反射发送实战(-)InvokeMember

原创 2004年08月24日 09:58:00

反射是.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
{
   
///
   
/// Class1 的摘要说明。
   
///
    class Class1 { ///
       
/// 应用程序的主入口点。
       
///
        [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();
        }
    }

   
///
   
/// Reflection 的摘要说明。
   
///
    public class ReflectionTest
    {
       
//保存动态生成并编译的类的type对象
        Type theType = null;
       
//保存动态生成类的实例
        object theClass = null;

       
///
       
/// 供Client调用的方法
       
///
        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//调用方法时的参数数组
                );
        }

       
///
       
/// 运行时生成代码
       
///
        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");
        }
    }
}

程序运行结果:

Hello,World
Hello,World

.

.

.

Looping Elapsed milliseconds:93.75 for 100 iterations

Hello,World
Hello,World

.

.

.

Looping Elapsed milliseconds:2875 for 100 iterations

性能上不占优势,主要是因为要进行写文件和编译的工作,但是后面的方法会对性能进行优化,到最后一个方法时性能会有大幅提高,但是最后一种方法的实用性不如前两种。

java反射实战

《Java反射实战》—— Ira R.Forman 、Nate Forman第一章 一些基本知识 反射基础 类基础 使用方法我们经常碰到一些问题,而这些问题可以使用反射来简单并优雅的解决掉。如果没有反...
  • rjcs888
  • rjcs888
  • 2016年12月01日 22:57
  • 721

C#多线程处理webbrowser及InvokeMember(click)无响应的问题

多线程处理webbrowser的相关问题,并解决触发click事件,js无响应问题。 最近刚好碰上一个需求:循环遍历网页元素,找到innerText为指定的内容时,就模拟人工点击。 解决办法:使用...
  • cuoban
  • cuoban
  • 2014年12月07日 17:49
  • 829

Java反射研究和实践

Java反射研究和实践概述Java的反射机制是Java语言动态性的一种体现。反射机制是通过反射API来实现的,它允许程序在运行过程中取得任何一个已知名称的类的内部信息,包括其中的构造方法、声明的字段和...
  • fengyuzhengfan
  • fengyuzhengfan
  • 2015年12月02日 20:03
  • 981

反射型xss实战演示

我们知道,XSS攻击大致分为三种类型 :Persistent型(持久型),Non-persistent(反射型)及Dom-based型。而反射型是最常用,也是使用得最广的一种攻击方式。它通过给别人发送...
  • huli870715
  • huli870715
  • 2013年02月26日 21:21
  • 3509

Java反射实例(实战方能理解jdk的各种方法)

什么是反射?反射有什么用处? 1. 什么是反射? “反射(Reflection)能够让运行于JVM中的程序检测和修改运行时的行为。”这个概念常常会和内省(Introspection)混淆,以下是这...
  • hupoling
  • hupoling
  • 2017年05月17日 10:18
  • 380

android中反射技术使用实例

在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据...
  • DQ1005
  • DQ1005
  • 2016年05月22日 14:36
  • 2041

Camel in action 第一章译文(请勿用于商业用途)

1 First steps 1.        Camel 介绍 2.        Camel路由 First steps Apachecamel 是 一个开源的一体化框架,其目的是使一体化...
  • wcp137297478
  • wcp137297478
  • 2014年04月04日 23:05
  • 868

利用dynamic来提供动态方法的性能

前段时间做了一个worklist的项目,有部分是利用xml配置DICOM的tag,然后根据xml把DICOM的Dataset转为实体类,或者把实体类转为Dataset。 当中主要应用了反射来调用Dat...
  • muzizongheng
  • muzizongheng
  • 2013年07月10日 15:44
  • 758

Android 反射实战

前面做了很多个demo去学习如何反射字段,方法,代理之类的等等,有一些给了实际的应用,有一些没有,看起来似乎没有什么实际价值,所以现在给出一个实战,开发条件需要的是一个jar包,这里以com.qti....
  • qq_31726827
  • qq_31726827
  • 2015年12月08日 22:12
  • 1064

【项目实战】---邮件发送

注册好多网站的时候,都需要发送邮件,然后让注册的用户激活方可完成注册,不过话说回来,为什么注册的时候需要发送邮件呢?为什么不注册的时候直接激活呢?一定要收一封激活帐号的邮件?网站这样做的好处是什么?又...
  • u010850027
  • u010850027
  • 2016年01月04日 08:06
  • 2665
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:反射发送实战(-)InvokeMember
举报原因:
原因补充:

(最多只允许输入30个字)