利用反射动态调用类成员

利用反射动态调用类成员

 

如果想复用别人写的.NET程序但手上只有一个编译过的EXE,那么方法之一是用Reflection(反射)。下面是一些例子,初次上手的人可以参考。

先假设我们要复用的第三方应用程序EXE是由下面的代码编译成的:

using System;
namespace MyNamespace
{
 public class MyApp
 {
  public MyNestedObject myNestedObject=null;
  public class MyNestedObject{
   public string name;
  }
  public enum FourSeasonsEnum{
   spring, summer, autumn, winter
  }
  public MyApp(){
  }
  public MyApp(MyNamespace.MyForm form){
  }
  public MyNestedObject Foo1(FourSeasonsEnum season){
   return this.myNestedObject;
  }
  public string Foo2(){
   return "";
  }
  static void Main(){
  }
 }
 public class MyForm
 {
  public MyForm(){
  }
 }
}

以下是一些直接引用时常见的调用如何用Reflection来改写:

1. 用不含参数的构造函数生成对象

直接引用时,代码是

MyNamespace.MyApp app=new MyNamespace.MyApp();

用Reflection来调用的话就需要这么写(记得using System.Reflection)

Assembly assem=Assembly.LoadFile(@"C:\Home\Workspace\MyNamespace\myapp.exe");
Type MyAppType=assem.GetType("MyNamespace.MyApp");
ConstructorInfo MyAppType_Constructor=MyAppType.GetConstructor(new Type[]{});
object app=MyAppType_Constructor.Invoke(new object[]{});

2. 用含参数的构造函数生成对象

直接引用时,代码是

MyNamespace.MyApp app=new MyNamespace.MyApp(new MyNamespace.MyForm());

用Reflection来调用的话就需要这么写

Assembly assem=Assembly.LoadFile(@"C:\Home\Workspace\MyNamespace\myapp.exe"); 
Type MyAppType=assem.GetType("MyNamespace.MyApp"); 
Type MyFormType=assem.GetType("MyNamespace.MyForm");
ConstructorInfo MyAppType_Constructor=MyAppType.GetConstructor(new Type[]{MyFormType});
ConstructorInfo MyFormType_Constructor=MyFormType.GetConstructor(new Type[]{});
object form=MyFormType_Constructor.Invoke(new object[]{});
object app=MyAppType_Constructor.Invoke(new object[]{form});

3. 调用对象的方法

直接引用时,代码是

MyNamespace.MyApp app=new MyNamespace.MyApp();
string str=app.Foo2();

用Reflection来调用的话就需要这么写

Assembly assem=Assembly.LoadFile(@"C:\Home\Workspace\MyNamespace\myapp.exe");
Type MyAppType=assem.GetType("MyNamespace.MyApp");
ConstructorInfo MyAppType_Constructor=MyAppType.GetConstructor(new Type[]{});
object app=MyAppType_Constructor.Invoke(new object[]{});
object str=MyAppType.GetMethod("Foo2").Invoke(app,new object[]{});

4. Set/Get成员变量

直接引用时,代码是

MyNamespace.MyApp app=new MyNamespace.MyApp();
MyNamespace.MyApp.MyNestedObject obj=app.myNestedObject;
MyNamespace.MyApp.MyNestedObject obj2=new MyNamespace.MyApp.MyNestedObject();
app.myNestedObject =obj2;

用Reflection来调用的话就需要这么写(注意,这里的MyNestedObject类是nested type,名字要用”MyNamespace.MyApp+MyNestedObject”而不是”MyNamespace.MyApp.MyNestedObject”)

Assembly assem=Assembly.LoadFile(@"C:\Home\Workspace\MyNamespace\myapp.exe");
Type MyAppType=assem.GetType("MyNamespace.MyApp");
ConstructorInfo MyAppType_Constructor=MyAppType.GetConstructor(new Type[]{});
object app=MyAppType_Constructor.Invoke(new object[]{});
Type MyNestedObjectType=assem.GetType("MyNamespace.MyApp+MyNestedObject");
FieldInfo MyNestedObjField=MyAppType.GetField("myNestedObject");
object obj=MyNestedObjField.GetValue(app);
    
ConstructorInfo MyNestedObjectType_Constructor=MyNestedObjectType.GetConstructor(new Type[]{});
object obj2=MyNestedObjectType_Constructor.Invoke(new object[]{});
MyNestedObjField.SetValue(app,obj2);

5. 使用枚举类型

直接引用时,代码是

MyNamespace.MyApp app=new MyNamespace.MyApp();
MyNamespace.MyApp.MyNestedObject obj=app.Foo1(MyNamespace.MyApp.FourSeasonsEnum.spring);

用Reflection来调用的话就需要这么写

Assembly assem=Assembly.LoadFile(@"C:\Home\Workspace\MyNamespace\myapp.exe");
Type MyAppType=assem.GetType("MyNamespace.MyApp");
ConstructorInfo MyAppType_Constructor=MyAppType.GetConstructor(new Type[]{});
object app=MyAppType_Constructor.Invoke(new object[]{});
Type FourSeasonsEnumType=assem.GetType("MyNamespace.MyApp+FourSeasonsEnum");
Array FourSeasonsEnumValues=Enum.GetValues(FourSeasonsEnumType);
object SpringValue=FourSeasonsEnumValues.GetValue(0);
object result=MyAppType.GetMethod("Foo1").Invoke(app,new object[]{SpringValue});

—

最后,只要有可能,应该尽量不用Reflection,因为相比起直接调用,Reflection的性能相当差。

转载于:https://www.cnblogs.com/liuzhiwei/archive/2005/12/05/291385.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/111157.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • minicom指令_如何优雅地使用minicom

    minicom指令_如何优雅地使用minicomminicom简介安装minicom是linux下一款常用的串口调试工具。ubuntu环境下,使用如下命令安装sudoapt-getinstallminicom配置使用前需要进行配置,执行sudominicom-s可打开minicom并进入配置模式,使用方向键,选择需要配置的项目,如Serialportsetup,回车进入配置,可以看到多个配置项,此时光标在最下方。需要修改某个配…

    2022年6月8日
  • pycharm django环境搭建_创建web项目

    pycharm django环境搭建_创建web项目1、Python环境搭建博主版本选择:Python2.7.15、Django1.11.82、pycharm安装pycharm激活成功教程版下载地址: 3、pycharm创建Django项目在软件安装和环境配置完成后,打开Pycharm.Step1.点击 File–>NewProject 弹出如下窗口Step…

    2022年8月25日
  • 了解图形数据库_图形数据库neo4j

    了解图形数据库_图形数据库neo4j企业架构师应该知道什么您在Google上获得的图表数据库的描述主要是学术性的。我看到很多关于图形数据库的描述,它们讨论了Königsberg的七座桥梁或互联网的发明者Berners-Lee。有理论和愿景很好,但对我来说,我仍然认为引导相关性很重要。为什么图形数据库对您很重要?想象一下存储在当地连锁餐厅的数据。如果您要跟踪,则将客户信息存储在一个数据库表中,将您提供的项目存储在另一个数据…

    2022年10月29日
  • 移动端开发绪论

    移动端开发绪论移动端开发基础通常移动端开发主流方案一共有两种一种是单独制作移动端页面,目前在市场上是主流方案还有一种是响应式页面兼容移动端这种虽然不是主流方案,但是应用这种开发方案的也不是没有.我们访问移动端页面可以通过以下两种方式进行访问:网址域名加m(mobile)就可以直接访问页面的移动端页面使用移动设备,进行访问,则可以直接跳转到移动端页面又到了我们最头疼的浏览器的兼容性问题移动端浏览器基本以webkit内核为主,因此我们只需要考虑webkit兼容性问题即可。移动端浏览器

    2022年6月24日
  • landsat 卫星波段组合以及envi下的展示

    landsat 卫星波段组合以及envi下的展示LandsatTM(ETM+)7个波段可以组合很多RGB方案用于不同地物的解译,Landsat8的OLI陆地成像仪包括9个波段,可以组合更多的RGB方案。OLI包括了ETM+传感器所有的波段,为了避免大气吸收特征,OLI对波段进行了重新调整,比较大的调整是OLIBand5(0.845–0.885μm),排除了0.825μm处水汽吸收特征;OLI全色波段Band8波段范围较窄,这种方式

    2022年7月23日
  • c语言删除数组中的元素「建议收藏」

    c语言删除数组中的元素「建议收藏」删除一个元素,相同也可删除核心思想:1.找到元素用if语句2.删除就是用后面的代替该元素(需要删除的元素),用for语句3.遍历(就是用for循环看一遍数列)就可以找到想要删除的元素,4.注意最后要给末尾换成零,因为后面的是随机的不一定为零#include<stdio.h>intmain(){ inti,a[10]; intb,c; //输入数组值 printf(“输入数组的值”); for(i=0;i<10;i++) { scanf(“%d”

    2022年7月22日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号