zoukankan      html  css  js  c++  java
  • 什么是反射?

    ①什么是反射?
    反射提供了封装程序集、模块和类型的对象。
    您可以使用反射动态地创建类型的实例(见④ ),将类型绑定到现有对象(这个不会),或从现有对象中获取类型(见②③ )。然后,可以调用类型的方法或访问其字段和属性。
    最最简单的反射:如下
    using System;
    using System.Reflection;
    namespace TestReflection
    {
        class Program
        {
            static void Main(string[] args)
            {
                //创建两个对象【object和Objetct好像没有区别啊??连提示都一样!】
                object A = new AX();
                Object B = new AXzhz();
                //获取对象的类型
                new TestObjectType().TestObjectTypeNow(A, B);           
            }
        }

        class AX
        {
        }

        class AXzhz
        {
        }

        class TestObjectType
        {
            //构造函数的默认修饰为private
            internal void TestObjectTypeNow(object A, object B)
            {
                Type tpA = A.GetType();
                Type tpB = B.GetType();
                Console.WriteLine(tpA.FullName);
                Console.WriteLine(tpB.FullName);
                Console.ReadLine();
            }
        }
    }
    输出结果:
    TestReflection.AX
    TestReflection.AXzhz
    【分析】通过对象实例(A,B),可以使用GetType()方法获取该对象属于哪个类.非类型转化后的类,而是构造该类型的类
    【应用】给个变量/对象实例,测试下它属于哪个类,顺带还给出该类所属的Assembly
    【附】另外一种获取类型的方法是通过Type.GetType以及Assembly.GetType方法,如:
           Type t = Type.GetType("TestReflection.AX");
        需要注意的是,前面我们讲到了命名空间和装配件的关系,要查找一个类,必须指定它所在的装配件
    Type类:表示类型声明:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。     发晕,对泛型没研究.

    ②我们获得的Type实例有什么用?
       ⅰ获得类名:如上面例子的FullName属性,返回TestReflection.AX
           这个也比较恶心,直接用A.ToString();返回的也是这个结果.
       ⅱ创建该类的对象.你首先通过ⅰ来获得类名AX
           AX ax = (AX)Activator.CreateInstance(tpA);
           都知道是AX类型了,怎么不new一个???鸡肋的东西.
          上面的【附】真不知道是干嘛吃的,都知道了类TestReflection.AX,直接new一个就可以了.
        ⅲ获得对象所属类的相关信息
             通过tpA的相关属性,来得到该类的相关信息.
             其实你通过A的相关属性,也可以得到该类的相关信息.还简单省事,真不知道Type类到底是干嘛吃的.

    ③窥一斑而知全豹,一个对象实例泄漏的密秘(这个比较爽)
    通过一个对象实例,我们可以获得包含这个对象实例的类的Assembly,进而获得整个Assembly的信息.


    using System;
    using System.Reflection;
    namespace TestReflection
    {
        class Program
        {
            public static void Main(string[] args)
            {
                object A = new AX();
                //获取对象所属的Assembly的所有类的基本信息
                new TestObjectType().TestObjectTypeNow(A);
            }
        }

        class AX
        {
            internal int kkkkkkkk = 0;
            public int ooooooooo;
            private int property;

            public int Property
            {
                get { return property; }
                set { property = value; }
            }
            public void A()
            {
                Console.WriteLine("AX's function!~");
            }
        }

        class AXzhz
        {
        }

        class TestObjectType
        {
            //构造函数的默认修饰为private
            internal void TestObjectTypeNow(object A)
            {
                Type tpA = A.GetType();
                Assembly assembly = tpA.Assembly;
                Type[] types = assembly.GetTypes();
                foreach (Type type in types)
                {
                    Console.WriteLine("【类名】"+type.FullName);
                    //获取类型的结构信息
                    ConstructorInfo[] myconstructors = type.GetConstructors();
                    Show(myconstructors);
                    //获取类型的字段信息
                    FieldInfo[] myfields = type.GetFields();
                    Show(myfields);
                    //获取方法信息
                    MethodInfo[] myMethodInfo = type.GetMethods();
                    Show(myMethodInfo);
                    //获取属性信息
                    PropertyInfo[] myproperties = type.GetProperties();
                    Show(myproperties);
                    //获取事件信息,这个项目没有事件,所以注释掉了,
                    //通过这种办法,还可以获得更多的type相关信息.
                    //EventInfo[] Myevents = type.GetEvents();
                     //Show(Myevents);
                }
                Console.ReadLine();
            }
            //显示数组的基本信息
            public void Show(object[] os)
            {
                foreach (object var in os)
                {
                    Console.WriteLine(var.ToString());
                }
                Console.WriteLine("----------------------------------");
            }
        }
    }

    【注】通过测试,发现只能获得public类型的信息.

    ④动态创建对象实例【经典】
    是实现抽象工厂的基础,也是实现抽象工厂的核心技术,通过它,可以动态创建一个你想要的对象.如下面的例子是演示如何动态创建ChineseName或EnglishName的实例


       1using System;
    using System.Reflection;
    namespace TestReflection
    {
        class AXzhz_sReflectionExample
        {
            public static void Main()
            {
                IName name=AbstractFactory.GetName();
                name.ShowName();
            }
        }

        public class AbstractFactory
        {
            public static IName GetName()
            {
                //s的值以后从Web.config动态获取
                //把s赋值为:TestReflection.EnglishName,将显示英文名
                string s = "TestReflection.ChineseName";
                IName name = (IName)Assembly.Load("TestReflection").CreateInstance(s);
                return name;
            }
        }
       
        //声明一个接口,它有一个显示"名字"的功能
        public interface IName
        {
            void ShowName();
        }

        //实现接口,显示中国名字
        public class ChineseName : IName
        {
            public void ShowName()
            {
                Console.WriteLine("我叫AX!");
                Console.ReadLine();
            }
        }

        //实现接口,显示英国名字
        public class EnglishName:IName
        {
            void IName.ShowName()
            {
                Console.WriteLine("My name is AXzhz!");
                Console.ReadLine();
            }
        }
    }
    ⑤获得整个解决方案的所有Assembly(这个有点用)
    如果你不太清楚自己的解决方案中都用到了哪些Assembly,可以使用下面的方法,如果再想得到Assembly里的信息,见③

    using System;
    using System.Reflection;

    namespace TestReflection
    {
        class ShowAllAssembly
        {
            public static void Main()
            {
                //获得解决方案的所有Assembly
                Assembly[] AX = AppDomain.CurrentDomain.GetAssemblies();
                //遍历显示每个Assembly的名字
                foreach (object var in AX)
                {
                    Console.WriteLine("Assembly的名字:"+var.ToString());               
                }
                //使用一个已知的Assembly名称,来创建一个Assembly
                //通过CodeBase属性显示最初指定的程序集的位置
                Console.WriteLine("最初指定的程序集TestReflection的位置:" + Assembly.Load("TestReflection").CodeBase);
                Console.ReadLine();
            }
        }
    }

    (出处:http://blog.csdn.net/shuilv2000/archive/2009/10/26/4728991.aspx

  • 相关阅读:
    POJ 1141 括号匹配 DP
    881. Boats to Save People
    870. Advantage Shuffle
    874. Walking Robot Simulation
    文件操作
    861. Score After Flipping Matrix
    860. Lemonade Change
    842. Split Array into Fibonacci Sequence
    765. Couples Holding Hands
    763. Partition Labels
  • 原文地址:https://www.cnblogs.com/guanjie20/p/1624176.html
Copyright © 2011-2022 走看看