欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

c#反射调用方法示例

程序员文章站 2024-02-22 18:27:46
获取方法的相关信息的两种形式 反射是一种允许用户获得类信息的c#功能,type对象映射它代表的底层对象; 在.net 中, 一旦获得了type对象,就可以使用getme...

获取方法的相关信息的两种形式

反射是一种允许用户获得类信息的c#功能,type对象映射它代表的底层对象;

在.net 中, 一旦获得了type对象,就可以使用getmethods()方法获取此类型支持的方法列表;该方法的两种形式:

methodinfo [] getmethods()

methodinfo [] getmethods(bindingflags bindingflas)  :它的参数带有一些限制 bindingflags  是一个枚举

枚举成员 [declaredonly,instance ,public]   枚举成员的功能使用  在编译器中使用"."符号后自己认真观察 【相信你很快能够理解】

parameterinfo[]  getparameters() 方法返回一个方法的参数列表

下面用到的类 myclass ,为了方便阅读,我把它折叠了!

复制代码 代码如下:

class myclass
    {
        int x;
        int y;
        public myclass(int i, int j)
        {
            this.x = i;
            this.y = j;
        }
        public int sum()
        {
            return x + y;
        }
        public bool isbetween(int i)
        {
            if (x < i && i < y)
            {
                return true;
            }
            return false;
        }
        public void set(int a, int b)
        {
            x = a;
            y = b;
        }
        public void set(double a, double b)
        {
            x = (int)a;
            y = (int)b;
        }
        public void show()
        {
            console.writeline("x: " + x + "  y:  " + y);
        }
    }

myclass

main:

复制代码 代码如下:

type t = typeof(myclass);//获得一个表示myclass类的type对象
            console.writeline("获取当前成员的名称" + t.name);
            console.writeline("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
            console.writeline("支持的方法");
            #region 第一种形式
            //methodinfo[] mi = t.getmethods();//显示class类中被支持的方法
            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            //方法getmethods() 把 myclass 的基类 object方法都显示出来了
            //下面我们说说  getmethods() 的另外一种形式,有限制的显示
            #endregion
            #region 第二种形式
            methodinfo[] mi = t.getmethods(bindingflags.declaredonly | bindingflags.instance | bindingflags.public);
            #endregion
            foreach (methodinfo m in mi)
            {
                //返回后打印出myclass类中成员的类型(方法的返回值类型)极其方法名称
                console.write("  " + m.returntype.name + "  " + m.name + " (");//returntype获取此方法的返回类型
                parameterinfo[] pi = m.getparameters();//获得方法的参数
                for (int i = 0; i < pi.length; i++)
                {
                    console.write(pi[i].parametertype.name + "   " + pi[i].name);//parametertype 获取该参数的type(类型)
                    if (i+1<pi.length)
                    {
                        console.write(", ");
                    }

                }
                console.writeline(")");
                console.writeline();
            }       

            console.readkey();

  
使用反射调用方法

上面 讨论了怎么获取一个类型所支持的方法,然而为我们获取对方法的调用做了充分的准备!

methodinfo类中的invoke() 方法提供了该技能!

它的一种形式:  object invoke(object  obj,object [] paramenters)

obj 是一个对象引用,将调用它所指向的对象上的方法,对于static方法,obj必须为null。

所有需要传递给方法的参数都必须在parameters数组中指定。如果方法不需要参数,则paramenters必须为null

基类methodbase的 invoke()方法返回被调用方法的返回值

请看下面的事例:

 

myclass类set()方法有所改变:

复制代码 代码如下:

public void set(int a, int b)
        {
console.writeline("set(int,int)");
x = a;
y = b;
show();
        }
        public void set(double a, double b)
        {
console.writeline("set(double,double)");
x = (int)a;
y = (int)b;
show();
        }

复制代码 代码如下:

type t = typeof(myclass);
myclass reflectob = new myclass(10, 20);
int val;
console.writeline("invoke methods in " + t.name);//调用myclass类的方法
console.writeline();
methodinfo[] mi = t.getmethods();

foreach (methodinfo m in mi)//调用每个方法
{
    //获得方法参数
    parameterinfo[] pi = m.getparameters();
    if (m.name.equals("set",stringcomparison.ordinal)&&pi[0].parametertype==typeof(int))
    {
        //     指定 system.string.compare(system.string,system.string) 和 system.string.equals(system.object)
        //     方法的某些重载要使用的区域、大小写和排序规则。
        //stringcomparison.ordinal   使用序号排序规则比较字符串
        object[] obj = new object[2];
        obj[0] = 9;
        obj[1] = 18;
        m.invoke(reflectob, obj);
    }
    else if (m.name.equals("set",stringcomparison.ordinal)&&pi[0].parametertype==typeof(double))
    {
        object[] obj = new object[2];
        obj[0] = 1.12;
        obj[1] = 23.4;
        m.invoke(reflectob, obj);
    }
    else if (m.name.equals("sum",stringcomparison.ordinal))
    {
        val = (int)m.invoke(reflectob, null);
        console.writeline("sum is : " + val);
    }
    else if (m.name.equals("isbetween", stringcomparison.ordinal))
    {
        object[] obj = new object[1];
        obj[0] = 14;
        if ((bool)m.invoke(reflectob, obj))
        {
console.writeline("14 is between x and y");
        }
    }
    else if (m.name.equals("show",stringcomparison.ordinal))
    {
        m.invoke(reflectob,null);
    }
}

main