zoukankan      html  css  js  c++  java
  • 反射可以动态调用对象(一般是类)的名称,属性,方法等。具体见下。重要

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

    反射是一种允许用户获得类信息的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

    自动驱动未来
  • 相关阅读:
    JMeter java模拟多用户高并发请求测试(json,form表单)
    mysql 存储过程 示例
    在C#中如何设置DateTimePicker控件显示“年-月-日 时:分:秒”的格式
    U盘或光盘启动的Win7-8-10的PE系统制作步骤
    SuperMap Objects中如何正确获取选择Selection以及提示“遇到一个未知错误,请重新打开窗口。ErrorMessage:尝试读取或写入受保护的内存。这通常指示他内存已损坏”
    C#中定义委托的思路
    docker(5):数据的管理
    docker(4)docker的网络,自定义网桥
    docker(3)容器管理命令
    docker (2) 通用/镜像命令
  • 原文地址:https://www.cnblogs.com/rb-huang/p/13739600.html
Copyright © 2011-2022 走看看