zoukankan      html  css  js  c++  java
  • C#基础知识回顾-- 反射(4)

    从程序集获得类型

      先说点题外话,现在技术真的发展太快了。我这边还很多东西半生不熟

    呢,那边又出现了好多有趣的新东西让你眼红不已。学还是不学这还真是

    个问题。Node.js 、bootstrap,我最近刚发现的新技术,其实他们已经

    存在很久了,只是没有接触过而已。昨天晚上看Node.js一下子看到两点

    多,感觉真是太有意思了^,有兴趣的可以去看看,大家多交流交流.

      好了不废话了,在前面的示例中,几乎全部的MyClass信息都是通过反射得到的,但是有一个例外:

    MyClass类型本身。虽然前面的示例可以动态确定MyClass的信息,但它们仍基于以下事实:事先知道

    类型名MyClass,并且在typeof语句中使用它创建一个Type对象。尽管这种方式可能在很多环境中都有

    用,但是要发挥反射的全部功能,就必须能通过分析其他程序集的内容动态的获取可用的类型。

      程序集提供了它包含的类和结构的信息。借助反射应用程序接口,可以加载程序集,获取它的相

    关信息并创建其公共可用类型的实例。通过使用这种机制,程序能够搜素其环境,利用那些潜在的功能而

    无需在编译期间显示的定义他们。由于类型的全部信息都可以被发现,因此不存在反射应用的内在限制。

    为了获取程序集的相关信息,首先需要创建一个Assembly对象。Assembly类并没有定义公有的

    构造函数,它的对象实例是通过类的一个方法获得的。这里使用的LoadFrom()方法可以加载由文件名

    指定的程序集,其形式如下:

      static Assembly LoadFrom(string fileName)

    一旦获得了Assembly类型的对象,就可以通过调用该对象的GetType()来得到它所定义的类型

    。基本形式如下:

      Type[] GetTypes()

      此方法返回一个数组,它包含了程序集的类型。

      为了说明如何获取程序集的类型,我们需要在解决方案中添加一个类库,类库名字为MyClasses,

    在类库中添加三个类:MyClass、AnotherClass、Demo。代码如下:

    程序集MyClasses代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace MyClasses
    {
        public class MyClass
        {
            int x;
            int y;
    
            public MyClass(int i)
            {
                Console.WriteLine("一个参数的构造函数:");
                x = y = i;
            }
            public MyClass(int i, int j)
            {
                Console.WriteLine("两个参数构造函数:");
                x = i;
                y = j;
    
                Show();
            }
    
            public int Sum()
            {
                return x + y;
            }
    
            public bool IsBetween(int i)
            {
                if (x < i && i < y)
                    return true;
                else
                    return false;
            }
    
            public void Set(int a, int b)
            {
                Console.Write("函数:Set(int a, int b)");
                x = a;
                y = b;
    
                Show();
            }
    
            public void Set(double a, double b)
            {
                Console.Write("函数:Set(double a, double b)");
    
                x = (int)a;
                y = (int)b;
    
                Show();
            }
    
            public void Show()
            {
                Console.WriteLine("x:{0},y:{1}", x, y);
            }
    
        }
    
        public class AnotherClass
        {
            string msg;
    
            public AnotherClass(string msg)
            {
                this.msg = msg;
            }
    
            public void show() {
                Console.WriteLine(msg);
            }
        }
        public class Demo
        {
            public void test()
            {
                Console.WriteLine("我是打酱油的!!");
            }
        }
    }

    使用反射代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Reflection;
    namespace Reflection
    {
        class Program
        {
            static void Main(string[] args)
            {
               
                ReflectAssemblyDemo();
                Console.ReadKey();
            }
    
    
            static void ReflectAssemblyDemo()
            {
                int val;
    
                Assembly asm = Assembly.LoadFrom("MyClasses.dll");
    
                Type[] allTypes = asm.GetTypes();
    
                foreach (Type type in allTypes)
                {
                    Console.WriteLine("程序集中找到类:" + type.Name);
                }
                Console.WriteLine();
    
                //使用第一个类
                Type t = allTypes[0];
    
                Console.WriteLine("使用类:" + t.Name);
    
                //获得构造函数
                ConstructorInfo[] ci = t.GetConstructors();
    
                //显示此类中的构造函数
                Console.WriteLine("此类中的构造函数有:");
    
                foreach (ConstructorInfo c in ci)
                {
                    Console.Write("  " + t.Name + " (");
    
                    ParameterInfo[] pi = c.GetParameters();
    
                    for (int i = 0; i < pi.Length; i++)
                    {
                        Console.Write(pi[i].ParameterType.Name + " " + pi[i].Name);
    
                        if (i + 1 < pi.Length) Console.Write(",");
                    }
    
                    Console.WriteLine(")");
                }
    
                //获取匹配的构造函数
    
                int x;
    
                for (x = 0; x < ci.Length; x++)
                {
                    ParameterInfo[] pi = ci[x].GetParameters();
                    if (pi.Length == 2) break;
                }
    
                if (ci.Length == x)
                {
                    Console.WriteLine("没有匹配的构造函数");
                    return;
                }
                else
                {
                    object[] consargs = new object[2];
    
                    consargs[0] = 10;
                    consargs[1] = 20;
    
                    object reflectOb = ci[x].Invoke(consargs);
    
                    Console.WriteLine("通过reflectOb调用方法");
    
                    Console.WriteLine();
    
                    MethodInfo[] mi = t.GetMethods();
    
                    foreach (MethodInfo m in mi)
                    {
                        //获得方法参数
    
                        ParameterInfo[] pi = m.GetParameters();
    
                        if (m.Name.CompareTo("Set") == 0 && pi[0].ParameterType == typeof(int))
                        {
                            object[] args = new object[2];
    
                            args[0] = 9;
                            args[1] = 18;
    
                            m.Invoke(reflectOb, args);
                        }
                        else if (m.Name.CompareTo("Set") == 0 && pi[0].ParameterType == typeof(double))
                        {
                            object[] args = new object[2];
    
                            args[0] = 1.25;
                            args[1] = 7.5;
    
                            m.Invoke(reflectOb, args);
                        }
                        else if (m.Name.CompareTo("Sum") == 0)
                        {
                            val = (int)m.Invoke(reflectOb, null);
    
                            Console.WriteLine("Sum is {0}", val);
                        }
                        else if (m.Name.CompareTo("IsBetween") == 0)
                        {
                            object[] args = new object[1];
    
                            args[0] = 13;
    
                            if ((bool)m.Invoke(reflectOb, args))
                            {
                                Console.WriteLine("13 is between x and y");
                            }
    
                        }
                        else if (m.Name.CompareTo("Show") == 0)
                        {
                            m.Invoke(reflectOb, null);
                        }
                    }
                }
            }
        }
    }

    运行结果:


      自此,反射部分基本内容写完了.希望对大家有所帮助.现在正在进行WPF开发,我会把在项目开发中遇到的问题与解决方案及时与您分享,希望您能继续关注.

      最后,如果本文对您有所帮助,请点推荐,谢谢!

     

  • 相关阅读:
    php 转化整型需要注意的地方
    生成6位随机数
    php://input
    ios常见问题 经验之谈
    ios 从前台返回到回台 从后台返回到前台 或者 支付宝支付订单后 对界面进行操作
    ios根据文本自适应 然后 搭建类似如下效果
    iosTableView 局部全部刷新以及删除编辑操作
    ios打开系统自带APP
    iOS通过URL Scheme启动app(收集了常用的app的URL Scheme)
    ios UIApplocation 中APP启动方式
  • 原文地址:https://www.cnblogs.com/smiler/p/3181239.html
Copyright © 2011-2022 走看看