zoukankan      html  css  js  c++  java
  • 反射

    反射

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

           再看一下运行结果:

     

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

    __喜欢的朋友别忘了推荐下,这里先谢了。。 ——我打远古走来,抖一身秦风汉雨,过一程唐关明月。累了,卧一卧高山大川。醒了,嗅一嗅明月星空。
  • 相关阅读:
    URAL 1998 The old Padawan 二分
    URAL 1997 Those are not the droids you're looking for 二分图最大匹配
    URAL 1995 Illegal spices 贪心构造
    URAL 1993 This cheeseburger you don't need 模拟题
    URAL 1992 CVS
    URAL 1991 The battle near the swamp 水题
    Codeforces Beta Round #92 (Div. 1 Only) A. Prime Permutation 暴力
    Codeforces Beta Round #7 D. Palindrome Degree hash
    Codeforces Beta Round #7 C. Line Exgcd
    Codeforces Beta Round #7 B. Memory Manager 模拟题
  • 原文地址:https://www.cnblogs.com/sjqq/p/6959519.html
Copyright © 2011-2022 走看看