准备项目 |
1.新建一个空的解决方案MyPRoj.sln 2.在该解决方案下,建一个控制台项目P01.csproj 3.在该项目下,自己新建一个类MyFirstClass.cs |
查看解决方案MyProj.sln,知道本次要编译哪个项目 |
查看项目文件P01.csproj(其实就是一个xml文档),可以知道本次程序会编译的类 |
类库编译成程序集 在bin目录下生成*.dll或*。exe 程序集包含哪些内容: 类型元数据【以二进制的形式,描述代码中定义的每一个类型和成员】 程序集元数据【程序集清单,版本号,名称等】 IL代码【这些都被装在exe或dll中】 资源文件【比如图片这些】 |
说明:程序集是在硬盘上的,如果每次要用到某个类的话,都去硬盘上读,速度会很慢, 所以VS会在程序第一次运行的时候,将程序集加载到内存中运行。 程序集(*.dll,*exe) -->加载到 内存中 就是Assembly对象 类(接口)--> 加载到内存中就是 Assembly下的Type对象 类的成员 --> 加载到内存 就是 Type下的相应对象(FieldInfo,PropertyInfo,MethodInfo,EventInfo) |
什么是反射: 1.在程序运行时, 动态 获取 加载程序集 动态 获取 类型(类,接口) 动态 获取 类型的成员 信息(字段,属性,方法) 2.在运行时, 动态 创建类型实例,以及 调用 和访问 这些 实例 成员 |
程序集(Assembly对象)===》类,接口(Type对象)===》类的成员(**Info) |
获取Assembly的方式: 获取当前 应用程序域中 所有的Assembly: AppDomain.CurentDomain.GetAssemblies(); 获取当前 对象 所在的 Assembly this.GetType().Assembly 根据路径加载Assembly Assembly.LoadFrom(命名空间.类名) |
获取Type对象的方式 1.通过类 获得 对应 Type:Type t = typeof(Person) 2.通过对象 获得 Type:Type t = p.GetType() 3.根据类的全名称 获取程序集中定义的类 Type type = Assembly.GetType(“命名空间.类名”) 4.获取程序集中定义的所有的public类 Type[] types = assembly.GetExportedTypes 5.获取程序集中定义的所有的类型 Type[] types = assembly.GetTypes() |
获取Type的成员 属性: type.Assembly:获取type所在程序集对象 type.FullName:获取type对象对应的类的全名称 type.Name:获取type对象对应类的 名称 type.IsArray:判断type是否为一个数组类 type.IsEnum:判断type是否为一个枚举类 方法: type.IsAssignableFrom(Type i):判断type是否实现了接口i type.IsSubclassOf(Type father):判断type是否继承了father type.IsInstanceOfType(object o):判断o是否为type类的实例 type.GetFiled(“gender“):获取type中名为gender的字段对象 type.GetProperty(“Age”):获取type中名为Age的属性对象 type.GetMethod(“SayHi”):获取type中名为SayHi的方法对象 |
static void Main(string[] args){ Dog dObj=new Dog() { dogName = "小白", dogAge = 1 }; Type dType = dObj.GetType(); //获取字段对象 FieldInfo fieldDogName = dType.GetField("dogName"); //获取dObj对象的dogName字段值,即dObj.dogName string strName = fieldDogName.GetValue(dObj) as string; //设置dObj里dogName字段赋值 fieldDogName.SetValue(dObj,"小黑"); Console.WriteLine(dObj.dogName); Console.ReadKey();}
反射-PropertyInfo属性对象
static void Main(string[] args){ Dog dObj = new Dog() {Name = "小白", Age = 1}; Type dType = dObj.GetType(); //获取属性对象 PropertyInfo proName = dType.GetProperty("Name"); //获取dObj对象的Name属性,即dObj.Name string strName = proName.GetValue(dObj) as string; //设置dObj里面Name属性值 proName.SetValue(dObj,"小黑"); Console.WriteLine(dObj.Name); Console.ReadKey();}
反射-MethodInfo方法对象
static void Main(string[] args){ Dog dObj=new Dog(); Type dType = dObj.GetType(); MethodInfo method = dType.GetMethod("Smile"); //普通调用方法 object res1 = dObj.Smile("小白"); //反射调用dObj的Smile方法,即dObj.Smile("小黑") //第一个参数是实例对象,第二个参数是方法的参数数组 object res2 = method.Invoke(dObj, new object[] {"小黑"}); Console.WriteLine(res1+" /n"+res2); Console.ReadKey();}
动态创建对象
static void Main(string[] args){ //方法一:通过Activator 动态创建对象 Type dType = typeof (Dog); //调用带两个参数的构造函数 Dog dogXB = Activator.CreateInstance(dType,new object[]{"小白",1}) as Dog; Console.WriteLine(dogXB.Name+"/t"+dogXB.Age); //方法二:使用 构造器 动态创建对象 Type dTypeXH = typeof (Dog); //获得 带两个参数的 构造函数 ConstructorInfo ctor = dType.GetConstructor(new Type[] {typeof (string), typeof (int)}); //创建 指定构造函数 Dog dogXH = ctor.Invoke(new object[] {"小黑", 2}) as Dog; Console.WriteLine(dogXH.Name+"/t"+dogXH.Age); Console.ReadKey();}
新闻热点
疑难解答