zoukankan      html  css  js  c++  java
  • 反射

    说起反射,我觉得就是窥探一个程序集内部的实现,基本上就是这个意思。

    并且反射无处不在,我们天天在使用,VS的智能提示就是通过反射获取到类的属性、方法等,还有反编译工具。
    反射就是动态获取程序集的元数据的来操作类型的,

    下面演示一下反射中得一些基本方法:

    首先建一个类库,写一些普通类、接口、抽象类、属性、方法等

    然后生成一下,将源文件中得dll拷贝到C盘下,这里这个dll文件就是程序集

    在主函数中调用:

    #region 加载指定的程序集,并且获取程序集中得所有类型
               // //写一个类,里面写一些类型,把生成的dll放到磁盘中
               // //加载ClassLibrary1.dll这个程序集,现在asm就是这个程序集
               // Assembly asm = Assembly.LoadFile(@"C:ClassLibrary1.dll");
    
               // //获取这个程序集中得类型名称(类名、枚举、接口、委托)
               // //这样搞会获取所有的(公有的私有的),那么面向对象那一套就不管用了
               ////Type[] getNames= asm.GetTypes();
    
               //Type[] getNames = asm.GetExportedTypes();//这种酒只能获取public了,别的都获取不到了
               //foreach (Type item in getNames)
               //{
               //    Console.WriteLine(item.Name);
               //}
                #endregion
    加载指定的程序集,并且获取程序集中得所有类型
    #region 加载程序集,获取Class1类下的所有方法
                //获取程序集
                Assembly asm = Assembly.LoadFile(@"C:ClassLibrary1.dll");
                     ////获取Class1这个类型,getClass1就表示Class1这个类型的元数据,它里面存了Class1的所有信息
                Type getClass1 = asm.GetType("ClassLibrary1.Class1");
                #region 获取所有非protected和非private方法
           
                ////获取Class1中得所有方法
                //MethodInfo[] getMathes = getClass1.GetMethods();
                ////遍历所有的方法
                //foreach (var item in getMathes)
                //{
                //    Console.WriteLine(item.Name);//会把所有的方法都打印出来包括ToString()啊Equals啊GetHashCode什么的
                //}
                #endregion
    
                #region 获取里面的方法,Class1里面有个SayHi方法
                MethodInfo method = getClass1.GetMethod("SayHi");
                //打印出方法名
                Console.WriteLine(method.Name);
    
                //创建一个类的对象,调用该方法
                object obj = Activator.CreateInstance(getClass1);
    
                //调用该方法
                method.Invoke(obj, null);//由于SayHi方法没有参数,这里Invoke方法的第二个参数就写null
                #endregion
    
                #endregion
    加载程序集,获取Class1类下的所有方法

    我们可以看到,反射中有很多地方会用到Type,它实现反射的一个重要的类,通过它我们可以获取类中的所有信息包括方法、属性等。可以动态调用类的属性、方法。它其实就是对类的描述,

     //加载程序集
                Assembly asm = Assembly.LoadFile(@"C:ClassLibrary1.dll");
                //获取Chinese类型的Type
                Type typeChinese = asm.GetType("ClassLibrary1.Chinese");
                //获取person类的Type
                Type typePerson = asm.GetType("ClassLibrary1.Person");
                //获取IJieKou接口的Type
                Type typeIJieKou = asm.GetType("ClassLibrary1.IJieKou");
                //获取CouXiang抽象类的Type
                Type typeCouXiang = asm.GetType("ClassLibrary1.CouXiang");
                //获取JinTai静态类的Type
                Type typeJinTai = asm.GetType("ClassLibrary1.JinTai");
    1 #region IsAssignableFrom方法
    2             //验证一下person类是不是chinese类的父类。在这里就是看能不能把chinese类赋值给person类
    3             bool b = typePerson.IsAssignableFrom(typeChinese);
    4             Console.WriteLine(b);//返回true,因为person类是chinese的父类
    5 
    6             //看一下接口行不行
    7             bool b1 = typeIJieKou.IsAssignableFrom(typeChinese);
    8             Console.WriteLine(b1);//也是true,
    9             #endregion
    IsAssignableFrom方法
    1 #region IsInstanceOfType方法
    2            Object obj = Activator.CreateInstance(typeChinese);
    3            //验证一下obj是不是Chinese类型的对象
    4            bool b2 = typeChinese.IsInstanceOfType(obj);
    5            Console.WriteLine(b2);//true
    6 
    7            bool b3 = typePerson.IsInstanceOfType(obj);
    8            Console.WriteLine(b3);//true
    9             #endregion
    IsInstanceOfType方法
    1   #region IsSubclassOf方法
    2             //验证Chinese是否是Person类的子类
    3            bool b4 = typeChinese.IsSubclassOf(typePerson);
    4            Console.WriteLine(b4);//true
    5 
    6             //验证chinese是否是IJieKou的子类
    7            bool b5 = typeChinese.IsSubclassOf(typeIJieKou);
    8            Console.WriteLine(b5);//返回false,因为接口只有实不实现,不存在子父类关系
    9            #endregion
    IsSubclassOf方法
    1   #region IsAbstract,判断某个类型是否是一个抽象的。
    2            Console.WriteLine(typeChinese.IsAbstract);//false
    3            Console.WriteLine(typePerson.IsAbstract);//false
    4             //接口、抽象类、静态类都不能被实例化,所以这里被认为是“抽象的”
    5            Console.WriteLine(typeIJieKou.IsAbstract);//true
    6            Console.WriteLine(typeJinTai.IsAbstract);//true
    7       
    8            #endregion
    IsAbstract,判断某个类型是否是一个抽象的

    通过反射获取类中得私有方法:

    首先写一个类,这里我就简单写一个方法:

    1 public class Person
    2     {
    3         private void Say()
    4         {
    5             Console.WriteLine("我是私有的。。");
    6         }
    7        
    8     }

    在主函数中通过反射去调用这个方法:

    1  static void Main(string[] args)
    2         {
    3             Type type=typeof(Person);
    4             MethodInfo method = type.GetMethod("Say", BindingFlags.NonPublic | BindingFlags.Instance);
    5             object obj = Activator.CreateInstance(type);
    6              method.Invoke(obj,null);
    7             Console.ReadLine();
    8         }
  • 相关阅读:
    hdu 5100 n*n棋盘放k*1长方条最多覆盖面积
    poj 3635/hdu 1676 Full Tank? 车辆加油+最短路
    poj 3613 经过k条边最短路 floyd+矩阵快速幂
    2014上海全国邀请赛 解题报告
    漫谈程序员系列:看看你离优秀有多远
    C2第七次作业解题报告
    C++ STL
    hdu 5098 双队列拓扑排序
    深度学习数据集 近百个开源数据集
    helper工具包——基于cifar10数据集的cnn分类模型的模块
  • 原文地址:https://www.cnblogs.com/tuibian/p/3642246.html
Copyright © 2011-2022 走看看