• 什么是反射?


    ①什么是反射?
    反射提供了封装程序集、模块和类型的对象。
    您可以使用反射动态地创建类型的实例(见④ ),将类型绑定到现有对象(这个不会),或从现有对象中获取类型(见②③ )。然后,可以调用类型的方法或访问其字段和属性。
    最最简单的反射:如下
    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

  • 相关阅读:
    工作总结系列---【端口被占用,如何取消端口进程】
    封装工具系列---【封装H5页面管理机构和证件类型下拉框数据处理的方法】
    工作总结系列---【vue页面实现导出表格效果】
    vscode---【内网开发下,离线安装vscode插件vsix文件】
    工作总结系列---【IDE深色背景下,鼠标移动也变成黑色,看不清怎么解决???】
    node系列---【为什么要设置镜像源?怎么配置?】
    git系列---【如何在本地修改别人的代码图解】
    git系列---【git如何回退到上一个版本??】
    封装工具系列---【补零操作】
    封装的各类工具系列---【时间格式化为YYYY-MM-DD格式 】
  • 原文地址:https://www.cnblogs.com/guanjie20/p/1624176.html
Copyright © 2020-2023  润新知