使用反射调用其它应用程序中的方法

    今天看到木帷幕一篇文章,讲到如何用反射调用别人的.net程序。遂自己也根据他的理念实作了一遍。

    我要调用的应用程序代码如下:
   
namespace MyClass
{
    
/// <summary>
    
/// Class2 的摘要说明。
    
/// </summary>
    public class UseClass
    {
        
protected int _account;
        
public UseClass()
        {
            _account
=0;
        }

        
public UseClass(int account)
        {
            _account
=account;
        }

        
public void AddAccount(int account)
        {
            _account
+=account;
            Console.WriteLine(_account);
            
        }

        
public void MulAccount(int account)
        {
            _account
-=account;
        }

        
public int ReturnAccount()
        {
            
return _account;
        }

    }
}


    一,首先我们要获得这个应用程序的Assmebly对象。然后才在这个对象上进行操作。

Assembly assemFile    =    Assembly.LoadFile(@"F:\Source\shipfi\MyTestCode\CSConsole\反射\被调用的类\MyClass\bin\Debug\myclass.exe");

    二,取得这个应用程序所需要的类的类型,这个Type是代表整个Class的。在这里是MyClass.UseClass类的类型。
   
Type myAppType    =    assemFile.GetType("MyClass.UseClass"); //获取UseClass类的类型

    三,获得类的构造函数信息,并且构造它。且构造函数的Type保存至一Type变量中,以后调用该类的方法时,需要用到该构造函数信息。这里我们用无参数的构造函数来构造:

ConstructorInfo cInfo    =    myAppType.GetConstructor(new Type[]{}); //获得UseClass的构造函数,并且,使用第一个不带参数的构造函数
object app    =    cInfo.Invoke(new object[]{}); //调用构造函数生成对象。

    如果要使用带参数的构造函数,可以像下面这样:
Type inttype    =    typeof(int);
ConstructorInfo cInfo2    
=    myAppType.GetConstructor(new Type[]{inttype});
object app2    =    cInfo2.Invoke(new object[]{4}); //_account的默认值为4

    这里,new Type[]{}大括号里面的参数得是Type类型,否则,如果写入int的话,编译器会出现错误。
    完成之后,app或app2就是代表了构造函数的信息。而myAppType则代表的是类的信息。下面就是调用类中的方法了。
//调用AddAccount(3)方法,设置_account为3
object str    =    myAppType.GetMethod("AddAccount").Invoke(app,new object[]{3});

    这里str保存的是函数返回值的信息,由于AddAccount返回值为Void.如果设置断点查看str的值的话,编译器会告诉你str是末定义的值。

    再来看另一个调用的方法:

object str2    =    myAppType.GetMethod("ReturnAccount").Invoke(app2,new object[]{});
Console.WriteLine((
int)str2); //这个ReturnAccount用得是带参数的构造函数,所以,这里输出为4

    由于ReturnAccount()是有返回类型,所以,str2可以转化为int类型输出。

以下是代码:
using System;
using System.Reflection;

namespace UseRefection
{
    
/// <summary>
    
/// Class1 的摘要说明。
    
/// </summary>
    class Class1
    {
        
/// <summary>
        
/// 应用程序的主入口点。
        
/// </summary>
        [STAThread]
        
static void Main(string[] args)
        {
            
//
            
// TODO: 在此处添加代码以启动应用程序
            
//
            Assembly assemFile    =    Assembly.LoadFile(@"F:\Source\shipfi\MyTestCode\CSConsole\反射\被调用的类\MyClass\bin\Debug\myclass.exe");
            Type myAppType    
=    assemFile.GetType("MyClass.UseClass"); //获取UseClass类的类型

            ConstructorInfo cInfo    
=    myAppType.GetConstructor(new Type[]{}); //获得UseClass的构造函数,并且,使用第一个不带参数的构造函数
            object app    =    cInfo.Invoke(new object[]{}); //调用构造函数生成对象。

            
//以下是生成一个UseClass对象,并且以有参数的构造函数来生成
            Type inttype    =    typeof(int);
            ConstructorInfo cInfo2    
=    myAppType.GetConstructor(new Type[]{inttype});
            
object app2    =    cInfo2.Invoke(new object[]{4});
            
            
//调用AddAccount(3)方法
            object str    =    myAppType.GetMethod("AddAccount").Invoke(app,new object[]{3});

            
//获得函数的返回值,并输出
            object str2    =    myAppType.GetMethod("ReturnAccount").Invoke(app2,new object[]{});
            Console.WriteLine((
int)str2);
            Console.ReadLine();
        }
    }
}


关于反射,有好多方法及属性,我对它们一知半解,唉~~~
posted @ 2005-09-24 10:14  shipfi  阅读(872)  评论(2编辑  收藏  举报