反射

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

并且反射无处不在,我们天天在使用,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         }
原文地址:https://www.cnblogs.com/tuibian/p/3642246.html