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);

                    }

                }

            }

        }

    }

}

运行结果:

 

C#基础知识回顾-- 反射(4)


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

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

 

你可能感兴趣的:(C#)