在学习反射之前,先了解一下什么是程序集?
net中的dll与exe文件都是程序集(区别,exe可执行,dll不可以)
程序集包含资源文件,类型元数据(也就是说属性、字段、参数、函数等)、IL代码,每个称袭击都有自己的名称、版本等信息
不添加引用时获取程序集的数据
而反射就是动态获取程序集的元数据
命名空间
System.Reflection
dll文件
namespace ReflectionTest { public class Person { public string Name { get; set; } public int Age { get; set; } public char Gender { get; set; } public virtual void Say() { Console.WriteLine("我是一个人"); } } class Teacher:Person { public override void Say() { Console.WriteLine("我是一名老师"); } } class Student : Person { public override void Say() { Console.WriteLine("我是一名学生"); } } }
方法
GetExportedTypes() 获取程序集中定义的公共类型
//AppDomain.CurrentDomain.BaseDirectory获取当前程序集目录,拼接上dll文件名 string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ReflectionTest.dll"); //加载程序集 Assembly ass = Assembly.LoadFile(path); //获取程序集中定义的公共类型 Type[] types = ass.GetExportedTypes(); foreach (Type item in types) { Console.WriteLine(item.Name); Console.WriteLine(item.FullName); Console.WriteLine(item.Namespace); }
GetTypes() 获取程序集定义的类型
//获取程序集定义的类型,包括internal类型,Teacher和Student类都没显示写访问修饰符 Type[] types = ass.GetTypes(); foreach (Type item in types) { Console.WriteLine(item.Name); Console.WriteLine(item.FullName); Console.WriteLine(item.Namespace); }
GetType() 获取程序集指定名称的System.Type对象
//获取程序集指定名称的System.Type对象 Type t = ass.GetType("ReflectionTest.Student"); Console.WriteLine(t.Name);
动态创建对象实例
CreateInstance()
//调用的是无参构造函数,所以当没有无参构造时,就会出错 object obj = ass.CreateInstance("ReflectionTest.Student"); Console.WriteLine(obj.GetType());
Activator.CreateInstace() 传参数(解决上面CreateInstance的问题)
Type t = ass.GetType("ReflectionTest.Student"); object obj = Activator.CreateInstance(t,"张三",18,'男'); Console.WriteLine(obj.GetType());
获取属性方法(包括父类的)
//获取类属性 PropertyInfo[] proInfo = obj.GetType().GetProperties(); foreach (PropertyInfo item in proInfo) { Console.WriteLine(item.Name); } //获取类方法 MethodInfo[] mInfo = obj.GetType().GetMethods(); foreach (MethodInfo item in mInfo) { Console.WriteLine(item.Name); }
方法调用
obj.GetType().GetMethod("Say").Invoke(obj, null);
常用方法
bool IsAssignableFrom(Type c) 判断当前的类型变量是不是可以接收c类型变量的赋值
bool IsInstanceOfType(object obj) 判断对象obj是否是当前类的实例(当前类可以是obj的类、父类、接口)
bool IsSubclassOf(Type c) 判断当前类是否是类c的子类(不包含接口)
bool IsAbstact 判断是否是抽象类