什么是反射?
反射是.net framework提供的一个帮助类库,可以访问dll/exe的metadata(元数据),并且使用他们。
元数据(Metadata),又称中介数据、中继数据,是为了描述数据的数据,主要是描述数据属性的信息,用来支持如指示存储位置、历史数据、资源查找、文件记录等功能。
使用反射
简单使用
#region 用反射机制获取程序集中的属性与方法(元数据){// 获取所在的dll的信息foreach (var item in assembly.GetModules()){// 获取dll的名称Console.WriteLine(item.Name);}// 获取dll的类型 {Name = "Student" FullName = "Models.Student"}foreach (var type in assembly.GetTypes()){Console.WriteLine(type.Name);// 获取指定类型的方法,方法中包含{字段的get,set方法、自定义方法、默认方法(Equals、GetHashCode、GetType、ToString等)}foreach (var method in type.GetMethods()){Console.WriteLine(method.Name);}}}#endregion
反射调用构造函数(IOC的雏形)
反射调用无参数构造函数
#region 用反射的机制创建对象(调用无参的构造函数){// 获取对应类型Type type = assembly.GetType("Models.Student");// 创建对象object vobj = Activator.CreateInstance(type);// 使用对象记得转换对象类型Student student = vobj as Student;// 使用对象方法student.write();}#endregion
反射调用带参数的构造函数
#region 调用带参数的构造函数{Type type = assembly.GetType("Models.Student");//创建一个带两个参数的构造函数object obj = Activator.CreateInstance(type, new object[] { 1,"zs" });//使用方法Student student = obj as Student;student.write();}#endregion
反射调用泛型类构造
#region 获取泛型类,调用泛型构造{//这里注意,使用`2的形式,指定类型的泛型参数格式Type type = assembly.GetType("Models.GenericStudent`2");Type typeGenereic = type.MakeGenericType(typeof(int), typeof(string));//调用泛型构造函数,构建对象object obj = Activator.CreateInstance(typeGenereic,new object[] { 1,"lisi"});//使用方法GenericStudent<int, string> student = obj as GenericStudent<int,string>;student.write();}#endregion
反射调用私有构造函数
#region 反射调用私有构造函数{// 用这种方式可以破坏单例模式Type type = assembly.GetType("Models.Teacher");// 调用私有构造函数,指定nonpublic为true,代表可以反问私有的构造方法。object obj = Activator.CreateInstance(type, true);}#endregion
反射调用方法
反射调用普通方法
#region 反射调用方法{Type type = assembly.GetType("Models.Student");object vobj = Activator.CreateInstance(type);MethodInfo methodInfo = type.GetMethod("write");methodInfo.Invoke(vobj, null);}#endregion
反射调用特殊方法(带参数的、静态的、重载的、私有的、泛型的)


调用泛型方法

反射动态获取/赋值属性字段
#region 反射动态获取/赋值属性字段//通常当使用到一个实体类的反射时,是不会从头(程序集Assmbly找起的){Type type = typeof(Student);// 实例化当前类型object obj = Activator.CreateInstance(type);//遍历获取类型判断并赋值foreach (var item in type.GetProperties()){if (item.Name.Equals("id")){item.SetValue(obj,1);}if (item.Name.Equals("name")){item.SetValue(obj, "lisi");}}}#endregion
泛型的好处与局限
好处:动态,将写死的东西可以用反射来动态来创建。
局限:
1、代码繁琐
2、反射能避开编译器的语法检查、编译检查,运行时才报错
3、性能问题(不是很大的问题):反射是普通方法的性能损耗百倍以上,但是绝对值还是蛮小的,几乎不影响项目的性能。
反射和缓存是离不开的,通常将固定的的反射的一些步骤缓存起来。而上一章的泛型缓存就非常适合。性能很高。
