程序集的反射

元数据表

程序集的元数据是用一系列表来存储的。生成一个程序集或者模块时,编译器会创建一个类型定义表、一个字段定义表、一个方法定义表以及其他表

 

反射的性能

  • 反射会造成编译时无法保证类型安全性。由于反射要严重依赖字符串,所以会丧失编译时的类型安全性。
  • 反射速度慢。使用反射时,类型及其成员的名称在编译时未知。要使用字符串名称表示每个类型及其成员,以便在运行时发现他们。也就是说,使用System.Reflection命名空间的类型扫描程序集的元数据时,反射要不断的执行字符串搜索和比较。

发现类型的成员

字段、构造器、方法、属性、事件和嵌套类型都可以被定义为一个类型的成员。下图显示了这些类型的层次结构:

 

image_thumb3

 

DeclaringType和ReflectedType(从MemberInfo派生的所有类型都通用的属性和方法)

public sealed class MyType
    {
        public override string ToString()
        {
            return null;
        }

        public void FunctionOne()
        {

        }

        /// <summary>
        /// Check if methods of MyType are DeclaringType or ReflectedType
        /// </summary>
        public void ShowIfDeclaringTypeOrReflectedType()
        {
            Type thisType = typeof(MyType);

            MemberInfo[] methodsInfos = thisType.GetMethods();

            foreach (var item in methodsInfos)
            {
                Console.WriteLine("Member name :{0}, DeclaringType: {1}, ReflectedType: {2}",
                    item, item.DeclaringType, item.ReflectedType);
            }
        }
    }

结果:

Member name :System.String ToString(), DeclaringType: TypesDemo.MyType, ReflectedType: TypesDemo.MyType
Member name :Void FunctionOne(), DeclaringType: TypesDemo.MyType, ReflectedType: TypesDemo.MyType
Member name :Void ShowIfDeclaringTypeOrReflectedType(), DeclaringType: TypesDemo.MyType, ReflectedType: TypesDemo.MyType

Member name :Boolean Equals(System.Object), DeclaringType: System.Object, ReflectedType: TypesDemo.MyType
Member name :Int32 GetHashCode(), DeclaringType: System.Object, ReflectedType: TypesDemo.MyType
Member name :System.Type GetType(), DeclaringType: System.Object, ReflectedType: TypesDemo.MyType

 

运行时类型

通过调用GetType方法可以知道一个实例的RuntimeType(CLR并没有暴露该类型)

    public class SuperClass
    {
    }

    public class SubClass : SuperClass
    {
    }
// Runtime type determination
            SuperClass superType = new SuperClass();
            SuperClass subType = new SubClass();
            Console.WriteLine("superType : {0}, subType : {1} ,Type of superType equals to subType : {2} "
                , superType.GetType(), subType.GetType(), superType.GetType() == subType.GetType());

运行结果:

superType : TypesDemo.SuperClass, subType : TypesDemo.SubClass ,Type of superType equals to subType : False

 

发现类型的接口

InterfaceMapping类型

字段名称 数据类型 说明
TargetType Type 这是用于调用GetInterfaceMapping的类型,即实现了接口的类型
InterfaceType Type 传给GetInterfaceMapping的接口类型
InterfaceMethods MemberInfo[] 一个数组,它的每个元素都暴露了一个与接口的方法有关的信息
TargerMethods MemberInfo[] 一个数组,它的每个元素都暴露了由类型定义的一个方法的信息,这个方法实现了接口中对应的方法
    internal interface IBookRetailer : IDisposable
    {
        void Purchase();
        void ApplyDiscount();
    }

    internal interface IMusicRetailer
    {
        void Purchase();
    }

    internal sealed class MyRetailer : IBookRetailer, IMusicRetailer, IDisposable
    {
        void IBookRetailer.Purchase() { }
        public void ApplyDiscount() { }

        void IMusicRetailer.Purchase() { }

        public void Dispose() { }

        public void Purchase() { }
    }

 

class Program
    {
        static void Main(string[] args)
        {
            // Find interfaces
            Type t = typeof(MyRetailer);
            // Get all interfaces define in current assmebly.
            Type[] interfaces=t.FindInterfaces(TypeFilter,typeof(Program).Assembly);
            Console.WriteLine("MyRetailer implements the following interfaces (defined in this assmebly):");
            foreach (Type i in interfaces)
            {
                Console.WriteLine("\nInterface: " + i);
                InterfaceMapping map = t.GetInterfaceMap(i);

                for (int m = 0; m < map.InterfaceMethods.Length; m++)
                {
                    Console.WriteLine(" {0} is implemented by {1}",
                        map.InterfaceMethods[m], map.TargetMethods[m]);
                }
            }
        }

        static Boolean TypeFilter(Type t, object filterCriteria)
        {
            return t.Assembly == filterCriteria;
        }
    }

运行结果:

Interface: TypesDemo.IBookRetailer
Void Purchase() is implemented by Void TypesDemo.IBookRetailer.Purchase()
Void ApplyDiscount() is implemented by Void ApplyDiscount()

Interface: TypesDemo.IMusicRetailer
Void Purchase() is implemented by Void TypesDemo.IMusicRetailer.Purchase()

posted @ 2012-09-18 00:22  HelloWorld.Michael  阅读(319)  评论(0编辑  收藏  举报