24.1 元数据和反射
有关程序及类型的数据被成为 元数据。他们保存在程序集中。
程序运行时,可以查看其他程序集或其本身的元数据。一个运行的程序查看本身元数据或其他程序的元数据的行为叫做 反射。
24.2 Type 类
| Name | 属性 | 返回类型的名字 |
| Namespace | 属性 | 返回包含类型的命名空间 |
| Assembly | 属性 | 返回声明类型的程序集。如果类型是泛型,返回定义这个类型的程序集 |
| GetFields | 方法 | 返回类型的字段列表 |
| GetProperties | 方法 | 返回类型的属性列表 |
| GetMethods | 方法 | 返回类型的方法列表 |
1.反射概念:
1.在程序运行时,
动态 获取 加载程序集
动态 获取 类型(如类、接口 等)
动态 获取 类型的成员 信息(如方法,字段,属性等);
2.在运行时,动态创建类型实例,以及 调用 和 访问 这些 实例 成员;
}
}
获取
调用
//6.相当于:d2.name=”小白”;
//7.相当于:d2.ShoutHi();
2.Assembly 程序集对象
获取程序集的方式:
2.1.获得当前 程序域中 所有的Assembly:
AppDomain.CurrentDomain.GetAssemblies()
Assembly[] ass = AppDomain.CurrentDomain.GetAssemblies();
ass调用的所有Assembly
2.2.获取当前 对象 所在的 Assembly:
this.GetType().Assembly
//1.获取当前正在运行的 程序集(Assembly)对象
Assembly ass = this.GetType().Assembly;
2.3.根据路径加载Assembly :
Assembly.LoadFrom(assPath)
3.Type 类型对象
Type类,程序运行时一个 class 对应一个 Type类的对象。
通过Type对象可以获得类的所有的定义信息,比如类有哪些属性、哪些方法等
获得Type对象的方式:
1.通过类 获得 对应 Type:Type t = typeof(Person)
2.通过对象 获得 Type:Type t = p.GetType()
3.根据类的全名称 获取程序集中定义的类:
Type type = Assembly.GetType("BLL.Person")
Type tDog = ass.GetType("_01反射.Dog"); //全名称(带命名空间)
4.获取程序集中定义的所有的public类:
Type [] types = assembly.GetExportedTypes()
5.获取程序集中定义的所有的类型:
Type [] types = assembly.GetTypes()
Assembly ass = this.GetType().Assembly;
//获取此程序集中定义的公共类型,这些公共(public)类型在程序集外可见. (ispublic = true)
Type[] types = ass.GetExportedTypes();
// 获取此程序集中定义的所有类型
Type[] tyoe = ass.GetTypes();
//1.通过类 直接过去 类型对象
Type t2 = typeof(Dog);
//2.通过对象 来获取 类型对象
Type t3 = this.GetType();
案例:笔记本插件开发
plugs文件夹
this.插件扩展ToolStripMenuItem.DropDownItems.Add(menuItem);
}
}
}
}
结果:
4.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.GetMethod("SayHi") |
获取type中名为 SayHi 的方法对象 |
| type.GetProperty("Age") | 获取type中名为 Age 的属性对象 |
5.FieldInfo 字段对象
FieldInfo类 代表某个类中的一个成员字段(类的全局变量)
int dogAge;
}
操作 对象 的字段
Dog dObj = new Dog() { dogName = "小花", dogAge = 1 }; //dogName:小花,dogAge:1 Console.WriteLine(string.Format("dogName:{0},dogAge:{1}",dObj.dogName,dObj.dogAge)); Type dType = dObj.GetType();//获取类型 FieldInfo fiDN = dType.GetField("dogName"); //获取字段对象 //相当于string strName = dObj.dogName; string strName = fiDN.GetValue(dObj).ToString(); //获取dObj的dogName字段值,strName=“小花” fiDN.SetValue(dObj, "小白"); //设置dObj里的dogName字段值 //dogName:小白,dogAge:1 Console.WriteLine(string.Format("dogName:{0},dogAge:{1}", dObj.dogName, dObj.dogAge));
6.PropertyInfo 属性对象
PropertyInfo类 代表某个类中的一个属性
int Age{get;set;}
}
Dog dObj = new Dog() { Name = "小花", Age = 1 }; Console.WriteLine(string.Format("dogName:{0},dogAge:{1}", dObj.Name, dObj.Age)); Type dType = dObj.GetType(); PropertyInfo piN = dType.GetProperty("Name"); //获取属性对象 string strName = piN.GetValue(dObj, null).ToString(); //获取dObj的Name属性值 piN.SetValue(dObj, "小白", null); //设置dObj里的Name属性值 Console.WriteLine(string.Format("dogName:{0},dogAge:{1}", dObj.Name, dObj.Age));
+name;
}
}
调用 对象 的方法
Dog dObj = new Dog(); Type dType = dObj.GetType(); MethodInfo method = dType.GetMethod("Smile"); //获取方法对象 object res1 = dObj.Smile("小五~~");//*普通调用方法 object res2 = method.Invoke(dObj, new object[] { "小白" }); //*反射调用dObj的Smile方法 Console.WriteLine(string.Format("res1:{0},\r\nres2:{1}", res1, res2));
第一个参数是实例对象,第二个参数是方法的参数数组,如果没有参数设置为null
问:如果第一个参数传 null 呢?
8.动态创建对象
1.object res =Activator.CreateInstance(Type type)
会动态调用类的无参构造函数创建一个对象
返回值就是创建的对象,如果类没有无参构造函数就会报错。
2.使用 构造器 创建
//构造函数 //public Dog(){} public Dog(string name, int age){ this.Name = name; this.Age = age; }
Type dType = typeof(Dog);//获取 Dog类 类型 对象 //获取 构造器 对象(根据 参数列表的 参数类型 数组 获取) ConstructorInfo cotr = dType.GetConstructor(new Type[] { typeof(string), typeof(int) }); object resValue = cotr.Invoke(new object[] { "小白", 2 }); //调用指定参数的实例所反映的构造函数cotr Console.WriteLine(string.Format("Name:{0},Age:{1}", ((Dog)(resValue)).Name, ((Dog)(resValue)).Age));
class Cat { public string name; public int age; //构造函数 public Cat(string name, int age) { this.name = name; this.age = age; } }
9.调用对象私有成员
null);
作者:唐三三
出处:http://tangge.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。