用反射调用别人的.NET程序里的类和方法

程序

如果想复用别人写的.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的性能相当差。

时间: 2024-09-20 23:34:31

用反射调用别人的.NET程序里的类和方法的相关文章

java-Jar包通过反射调用的问题

问题描述 Jar包通过反射调用的问题 我把一个程序打成jar包,如app.jar 改jar包中的一个方法通过反射调用了另一个jar包中的main方法.我用以下参数运行: java -jar app.jar "the_mainclass_to_call_by_reflection" -class-path . 得到异常:java.lang.ClassNotFoundException 我已确认:the_mainclass_to_call_by_reflection在classpath中

C#中派生类的方法里的匿名delegate调用基类的方法会产生无法验证的代码

看来阅读一个开发人员的blog是获取知识的一个捷径,特别是当那位开发人员负责的产品是你天天都用的基础设施之一,例如说--编译器.在阅读Eric Lippert的blog时,我无意中了解到了很多我以前所不熟悉的知识,例如说一些语言特性,一些编程思想之类:但更有趣的,我了解到了很多他所负责的产品中的诡异地方. 开篇花絮: 假如我们现在有一个枚举类型E,其中有一个枚举值的名字是x. 你或许知道这个表达式是对的: C#代码 0 | E.x 但是你或许不知道这个表达式(根据语言规范应该)是错的: C#代码

pb程序里如何调用vs2012编译的dll ,该dll是封装的第三方的webservice

问题描述 pb程序里如何调用vs2012编译的dll ,该dll是封装的第三方的webservice 第三方给了一个webservice,我用vs的命令,编译成了dll,可惜pb程序里无法正常调用该dll 解决方案 .net的dll,需要包装成com对象,才能被pb调用,不是一般的dll.关于如何包装com组件,以及pb如何调用com组件,请google. 解决方案二: pb程序里如何调用vs2012编译的dll ,该dll是封装的第三方的webservice 第三方给了一个webservice

r语言-在C# 程序里 调用R语言 调用完R语言后C#程序也跟着结束了,怎么让他不跟着结束呢?

问题描述 在C# 程序里 调用R语言 调用完R语言后C#程序也跟着结束了,怎么让他不跟着结束呢? 我程序里调用R语言的代码是这样的 REngine.SetEnvironmentVariables(); REngine engine = REngine.GetInstance(); engine.Evaluate(R_cmd); engine.Evaluate("q()"); engine.Dispose(); 这样有什么问题吗? 解决方案 你C#怎么写的?控制台程序可以加上一个Cons

大哥大姐救救我吧,如何让webservices里引用的dll程序调用应用程序里的方法

问题描述 如何让webservices里引用的dll程序调用应用程序里的方法 解决方案 解决方案二:你直接引用了,实例化后就提示它里面的方法了啊解决方案三:实例化之后不久可以调用了,解决方案四:同意楼上解决方案五:ding解决方案六:ding解决方案七:实在不行就regsvr32注册下dll

c#-窗体程序调用别人动态库成功,控制台应用程序不成功

问题描述 窗体程序调用别人动态库成功,控制台应用程序不成功 C#调用别人的动态库,用窗体程序调用成功 用控制台应用程序调用不成功 解决方案 1.在解决方案中添加引用:右键鼠标-->添加引用-->浏览-->选择dll放置路径后点击"确定". 2.在应用文件头处使用using ×××: 3.控制台下面在main中调用. 第一次回答问题,不知道对你有木有帮助

Java程序,点击按钮(调用其它包里类的方法,返回字符串)后,将返回的字符串显示到jPanel上

问题描述 Java程序,点击按钮(调用其它包里类的方法,返回字符串)后,将返回的字符串显示到jPanel上 怎么修改程序,点击按钮后,jPanel显示其它方法返回的字符串, 我是Java初学者,这个比较急,大家帮帮忙,有悬赏的! 解决方案 String rtn = model1.cutWord(//rtn是返回值 JLabel label1=new JLabel(rtn);//创建两个标签组件 label1.setText("使用方法进行设置 "); jPanel1.add(label

想问问我建立了一个webservice应用程序客户端,直接在程序里运行调用方法是对的,但进debug或release直接运行后就报错,这是为什么啊?

问题描述 想问问我建立了一个webservice应用程序客户端,直接在程序里运行调用方法是对的,但进debug或release直接运行后就报错,这是为什么啊?感觉就是不用程序直接运行的话,其他方法运行就报错误.里面什么其他的都没做,就是直接加了web引用,然后调了一个方法而已.谁能解答一下? 解决方案 解决方案二:up

程序里有JComboBox,它们触发了ItemListener事件,可是它总是显示两遍,这是怎么为什么啊?

问题描述 packagecom.ibm.iwt.example;importjava.awt.*;importjavax.swing.*;importcom.ibm.iwt.operateFile.OperateFile;importcom.ibm.iwt.operateFile.OperateRSS;importcom.ibm.iwt.window.IWindowComponent;importcom.sun.syndication.io.FeedException;importjava.aw