反射
反射式动态获取程序集的元数据的功能
VS的只能提示和反编译就是使用的反射。
反射的一个重要的类是Type,其可获得一个类型的类型,通过这个我们可以获取类中的所有信息,包括方法、属性。 可以动态调用类的属性、方法。
反射是通过.dll来创建对象,调用成员。
对于已经已经生成的类库,在另一个项目中引用时,可以通过反射获取该类库中的元数据。
1. 已写好的类库:Common.dll
Person.cs
using System; using System.IO; namespace Common { public class Person { public void Write() { Console.WriteLine("good cat"); } public int Age { get; set; } public string Name { get; set; } public void SayHi() { Console.WriteLine("Person Method"); } public Person(string name) { Name = name; } public Person() { } } class Cat { public string Eat { get; set; } string catName; } }
2. 将Common.dll文件拷贝到引用项目的可执行文件所在目录
3. 引用项目:
Program.cs
using System; using System.Collections.Generic; using System.IO; //Assembly using System.Reflection; namespace 反射 { class Program { static void Main(string[] args) { //添加引用有些麻烦,而且只能使用其中的公共成员 //对于给定的dll文件,想要使用里面的所有成员 //首先加载程序集文件 //获取当前程序的exe所在目录+文件名=文件所在的绝对目录 string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Common.dll"); Assembly asse = Assembly.LoadFile(path); Console.WriteLine("加载程序集成功。"); #region 获取程序集类型的3个函数 //获取程序集中的类型:公共和私有 Console.WriteLine("1. GetTypes()"); Type[] allTypes = asse.GetTypes(); foreach(Type item in allTypes) { Console.WriteLine(item.Name); Console.WriteLine(item.FullName); Console.WriteLine(item.Namespace); } Console.WriteLine(); //获取程序集中定义的公共类型,这些类型在程序集外可见 Console.WriteLine("2. GetExportedTypes()"); Type[] publicTypes = asse.GetExportedTypes(); foreach(Type item in publicTypes) { Console.WriteLine(item.Name); Console.WriteLine(item.FullName); Console.WriteLine(item.Namespace); } Console.WriteLine(); //获取单个类型 Console.WriteLine("3. GetTypes(\"Common.Person\").Name"); Type t = asse.GetType("Common.Person"); Console.WriteLine(t.Name); #endregion Console.WriteLine(); //从获取的类型来创建对象 //CreateInstance从程序集中查找指定的类型,然后使用系统激活器 //创建它的实例,调用了Person的默认无参数的构造函数,而不能调用 //有参的构造函数 Console.WriteLine("4. CreateInstance(\"Common.Person\").GetType()"); object o = asse.CreateInstance("Common.Person"); Console.WriteLine(o.GetType()); Console.WriteLine(); //可以指定要用的构造函数 Console.WriteLine("5. 指定要用的构造函数Activator来CreateInstance"); Type tt = asse.GetType("Common.Person"); object o1 = Activator.CreateInstance(tt,"PersonName"); PropertyInfo[] proInfos = o1.GetType().GetProperties(); foreach(PropertyInfo item in proInfos) { Console.WriteLine(item.Name); } Console.WriteLine(); MethodInfo[] mths = o1.GetType().GetMethods(); foreach (MethodInfo item in mths) { Console.WriteLine(item); } Console.WriteLine("获取指定函数的信息"); MethodInfo mdi = o1.GetType().GetMethod("SayHi"); //方法所属对象,函数参数列表 mdi.Invoke(o1,null); //IsAssignableFrom(Type c)判断当前的类型是否可以接收C类型变量的赋值 //typeof(IPlugin).IsAssignableFrom(t) //isInstanceOfType(object o):判断对象O是否为当前类的实例 //bool IsSubclassOf(Type c):判断当前类是否为c的子类 //IsAbstract判断是否为抽象,含接口 Console.ReadKey(); } } }
4. 输出