一、程序集
1、程序集
我们所写的所有代码都会编译到程序集文件中,并在运行时以Assembly对象方式加载到内存中运行。
2、程序集的组成
运行时:
程序集:*.exe,.dll—>加载到内存中就是Assembly对象
类:每个class,interface—>加载到内存中就是Type对象
类的成员:方法、字段、属性、事件---à加载到内存中也有相应的对象
二、反射
1、 在程序运行时,动态获取加载程序集,动态获取类型(如类、接口等),动态获取类的成员信息(如方法,字段,属性等)
2、 在运行时,动态创建类型实例,以调用和访问这些实例成员。
Demo
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 protected void Page_Load(object sender, EventArgs e) 2 { 3 //获取当前运行程序(应用程序域)里的程序集,也就是程序跑起来用到的程序集。 4 //Assembly[] ass = AppDomain.CurrentDomain.GetAssemblies(); 5 } 6 7 protected void Button1_Click(object sender, EventArgs e) 8 { 9 /**************************反射获取类的成员***********************************/ 10 //获取当前正在运行的程序集(Assembly)对象 11 Assembly ass = this.GetType().Assembly;//this表示当前窗体 12 //获取程序集中dog类的类型(Type)对象 13 Type tDog = ass.GetType("demo.Dog"); 14 //获取dog类的name字段 15 FieldInfo fInfo = tDog.GetField("name"); 16 //获取方法 17 MethodInfo mInfo = tDog.GetMethod("ShoutHi"); 18 19 /**************************反射调用类的成员***********************************/ 20 //根据Dog的Type对象,实例化一个Dog对象 21 Dog d2 = Activator.CreateInstance(tDog) as Dog;//只能调用无参的构造函数 22 //使用Dog类的name字段对象,为d2实例的name字段赋值 23 fInfo.SetValue(d2, "小白"); 24 //使用Dog类的ShoutHi方法对象,执行d2实例的ShoutHi方法 25 string strRes = mInfo.Invoke(d2, null) as string; 26 27 }
三、Assembly程序集对象
获取程序集的方式:
1、获得当前程序域中的所有Assembly:AppDomain.CurrentDomain.GetAssemblies() (如添加其他程序集,只有用到的时候才在程序域里面可以看到)
2、获取当前对象的所在的Assembly:this.GetType().Assembly;
3、根据路径加载Assembly:Assembly.LoadFrom(assPath)
获取目前正在运行的程序集的物理路径:
string strAssPath=this.GetType().Assembly.Location;
四、Type类型对象
获取Type对象的方式:
1、 通过类获取相应的Type:Type t=typeof(Person)
2、 通过对象获取Type:Type t=p.GetType()
3、 根据类的全名称,获取程序集中定义的类
Type type=Assembly.GetType(“BLL.Person”)
4、 获取程序集中定义的所有的puble类: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.GetMethod(“SayHi”) | 方法 | 获取type中名为”SayHi”的方法对象 |
type.GetProperty(“Age”) | 方法 | 获取type中名为”Age”的属性字段 |
六、方法对象
1、获取类中直接定义的(非继承),实例的,公共方法
MethodInfo[] methods=o.GetMethods(BindingFlags.DeclaredOnly|BindingFlags.Instance|BingingFlags.Public);// o为对象对应的Type
2、 获取类对象中的构造函数
ConstructorInfo[] constructors=t.GetConstructors();//t表示类获取相应的Type foreach(var c in constructors) { s+=c.GetParameters().Length.ToString();//获取构造方法的参数长度 }
如类Person,有三个构造函数Person(){},Person(string name){..},Person(string name,int age,bool gender),如何根据反射获取到构造函数?
//注意:Activator.CreateInstance(o) 只能调用无参的构造函数
Type t=typeof(Person); ConstructorInfo constructor=null; Person p=null;
//根据无参的构造函数获取对象:
constructor=t.GetConstructor(null); p= constructor.Invoke(null) as Person;
//通过三个参数的构造方法获取对象
constructor=t.GetConstructor(new Types[3]{typeof(string),typeof(int),typeof(bool)}); p= constructor.Invoke(new object[3]{“小王”,1,true}) as Person;