Fork me on GitHub
反射

反射

在看反射之前我们来看一下.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 });

       再看一下运行结果:

 

    好了,反射就介绍到这一块,由于我自己也是初学,难免有所错误,敬请谅解,欢迎和我交流。

posted on 2011-10-17 09:28  HackerVirus  阅读(175)  评论(0编辑  收藏  举报