添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

C# 编译后的文件主要由 IL 代码和元数据组成,元数据为 .NET 组件提供了丰富的自描述特性,它使得我们可以在代码运行时获知组件中的类型等重要的信息。 C# 中这是通过一种称作映射( Reflection )的机制来完成的。

动态类型查询

首先创建一个简单的类型

namespace ReflectionClass
    public class MyClass
        #region Property
        private int m_Count = 100;
        public int Count
                return m_Count;
                m_Count = value;
        #endregion
        #region Method
        public void Print()
            Console.WriteLine("MyClass.Count = {}", Count);
        #endregion

    编译后可以得到“ReflectionClass.dll”文件,接下来实现查询类型的测试程序:

namespace TestReflection
    public class App
        static void Main(string[] args)
            Type type = typeof(MyClass); //获取MyClass的类型信息
            Console.WriteLine("The Type Name : {0}", type.Name); //获取类型的名字
            FieldInfo[] fieldArray = type.GetFields(); //获取所有的公有域
            Console.Write("The {0} Fields : ", fieldArray.Length);
            foreach (FieldInfo field in fieldArray)
                Console.Write(field.Name + " ");
            Console.WriteLine();
            PropertyInfo[] propertyArray = type.GetProperties(); //获取所有的公有属性
            Console.Write("The {0} Properties : ", propertyArray.Length);
            foreach (PropertyInfo property in propertyArray)
                Console.Write(property.Name + " ");
            Console.WriteLine();
            MethodInfo[] methodArray = type.GetMethods(); //获取所有的公有方法
            Console.Write("The {0} Methods : ", methodArray.Length);
            foreach (MethodInfo method in methodArray)
                Console.Write(method.Name + " ");

      编译后执行,可以得到以下输出:

      The Type Name : MyClass

      The 0 Fields :

      The 1 Properties : Count

      The 7 Methods : get_Count set_Count Print ToString Equals GetHashCode GetType

      在上面的例子中,首先通过 typeof(MyClass)获得MyClass类的类型信息,当然也可以通过创建对象实例,然后调用对象实例的GetType方法来获得(每个类都从 object根类中继承获得此方法)。在拥有了类型信息(变量type)后,便可以获得其类型的名字、该类型含有的公有域、公有属性、公有方法。注意这里C#的映射机制只允许获取类型的公有信息,这符合面向对象的封装原则。其中4个方法(GetHashCodeEqualsToStringGetType)都是继承自object类的公有方法,而方法get_Count set_Count则是实现Count属性的副产物。实际上,System.Type类各种各样的成员使得我们能够获得几乎所有与类型相关的公有信息。在System.Reflection命名空间下的各个类都可以获得各个编程元素较详细的信息,如方法的参数与返回值、域的类型、枚举的各个值等

      动态创建与调用

      实际上映射远不止动态地获知组件的类型信息,它还能在获得类型信息的基础上,在代码运行时进行类型的动态创建与方法的动态调用。

namespace TestReflection2
    public class App
        static void Main(string[] args)
            Assembly assemlby = Assembly.LoadFrom("ReflectionClass.dll"); //装载组件
            foreach (var type in assemlby.GetTypes())
                if (type.IsClass && !type.IsAbstract)
                    MethodInfo[] methodArray = type.GetMethods(); //获得类型的公有方法
                    object obj = Activator.CreateInstance(type); //创建实例(无参构造器)
                    foreach (var method in methodArray)
                        if (!method.IsAbstract && !method.IsStatic && method.GetParameters().Length == 0)
                            object ret = method.Invoke(obj, null); //调用实例方法
                            Console.WriteLine("{0}'s Return : {1}", method.Name, ret);

      编译后执行,可以得到以下输出:

      get_Count's Return : 100

      MyClass.Count = 100

      Print's Return :

      ToString's Return : ReflectionClass.MyClass

      GetHashCode's Return : 62476613

      GetType's Return : ReflectionClass.MyClass

      在上面的例子中给出了被动态调用的方法名字和返回值。其中第二行输出的“MyClass.Count = 100”,它是动态调用方法MyClass.Print()的输出。需要指出的是调用的是类型的公有无参数实例方法。给出组件的名字,应用Assembly.LoadFrom,我们便可以动态地装载组件。 Activator.CreateInstance()允许动态地创建类型(这里只通过无参数的构造器来创建),实际上用它创建出来的类型和用MyClass obj = new MyClass()创建出来的类型一样。进而,还可以在查询到的成员的基础上,对它们进行动态调用。

      另外,还可以用“Assembly.CreateInstance()创建实例,从本质上讲,Assembly.CreateInstance()”就是调用的“Activator.CreateInstance()”。

声明:本文纯属个人随手笔记,如果对您有参考价值我十分开心,如果有存在错误,或者有更好的解决办法也麻烦您留言告诉我,大家共同成长,切勿恶言相。 欢迎加入MSDN技术交流群:235937854,一起发现知识、了解知识、学习知识、分享知识