反射
在看反射之前我们来看一下.Net源代码是怎么执行的:
我们看到.Net源代码是两次编译,一次执行的。在Visual Studio经过第一次编译生成程序集(.exe,.dll),就是IL(中间语言)和元数据,然后在经过CLR(公共语言运行库),将程序集编译成机器代码,机器代码在交给cpu去执行。
我们来看.Net源代码在第一次编译之后:
现在来看一下什么是反射,反射是编程的读取与类型相关联的元数据的行为。通读取元数据,可以了解它是什么类型以及类型的成员。比如类中的属性,方法,事件等。所属命名空间System.Reflection。
反射具体是怎么实现的,下面通过一个例子来具体说明。
首先在解决方案中新建一个项目:
新建的项目类型是个类库,一次编译后生成.dll文件,项目名为MyDemo,接下来在类库中定义一个Student类,定义两个字段,一个是name,一个是age,表示姓名和年龄
在创建Name,Age属性
在创建两个构造函数:
在创建几个方法:
到这一步这个类库就建好了,现在来生成一下,生成MyDemo.dll文件
在解决方案中在添加一个控制台项目,来实现对MyDemo.dll的反射
首先要取得该文件的路径,在得到程序集:
然后在得到MyDemo.dll中类的类型,并且实例化一个对象,有两种方法:
//类级别
//第一种方法,在类的构造函数是无参时使用方便,在有参时就不容易实现
object obj = ass.CreateInstance("MyDemo.Person");//实例化Person类,返回值是object,通过命名空间及类名得到
Type StuType = obj.GetType(); //得到类的类型
//第二种方法,通过获得类型的构造函数来实例化对象,在构造函数是有参时也容易实现
Type StuType = ass.GetType("MyDemo.Person");//得到类的类型
ConstructorInfo constructor = StuType.GetConstructor(new Type[0]);//得到StuType的构造函数(无参)
object obj = constructor.Invoke(null);//调用构造函数来实现实例化类
现在先通过调用无参构造函数来实例化类,下面看一下通过反射怎么得到类成员:
//类成员级别
MethodInfo method1 = StuType.GetMethod("SayName");//得到无参公有方法
MethodInfo method2 = StuType.GetMethod("SayAge", BindingFlags.Instance | BindingFlags.NonPublic);//得到私有方法
MethodInfo method3 = StuType.GetMethod("GetName", new Type[] { typeof(string) });//得到带参数的公有方法(后面的Type类型可以省略,但如果是重载方法就不能省)
MethodInfo method4 = StuType.GetMethod("GetName", new Type[0]);
MethodInfo method5 = StuType.GetMethod("PrintAge");//得到参数是ref的的方法
PropertyInfo Name = StuType.GetProperty("Name");//得到属性
PropertyInfo Age = StuType.GetProperty("Age");
FieldInfo name = StuType.GetField("name", BindingFlags.Instance | BindingFlags.NonPublic);//得到字段(全是私有的)
FieldInfo age = StuType.GetField("name", BindingFlags.Instance | BindingFlags.NonPublic);
Name.SetValue(obj, "李四",null);//给Name设值,后面的null是对应的索引器
Age.SetValue(obj, 23, null);
method1.Invoke(obj, null);
method2.Invoke(obj, null);
Console.WriteLine(method3.Invoke(obj, new object[] { "王五" }));//调用有返回值的方法
method4.Invoke(obj, null);
method5.Invoke(obj, new object[]{14});//调用参数是ref的方法
执行程序,看一下运行结果:
好,下面再看一下怎么调用有参的构造函数来实例化类:
Type StuType = ass.GetType("MyDemo.Person");
ConstructorInfo constructor = StuType.GetConstructor(new Type[] { typeof(string), typeof(int) });//构造函数
object obj = constructor.Invoke(new object[] { "张三", 20 });
再看一下运行结果:
好了,反射就介绍到这一块,由于我自己也是初学,难免有所错误,敬请谅解,欢迎和我交流。