• 反射


    反射

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

           再看一下运行结果:

     

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

    __喜欢的朋友别忘了推荐下,这里先谢了。。 ——我打远古走来,抖一身秦风汉雨,过一程唐关明月。累了,卧一卧高山大川。醒了,嗅一嗅明月星空。
  • 相关阅读:
    [刷题] IDA*
    [BZOJ1330] Editing a Book
    [BZOJ5449] 序列
    [刷题] 搜索剪枝技巧
    [XJOI3529] 左右
    [CF920E] Connected Components?
    [第18届 科大讯飞杯 J] 能到达吗
    洛谷 P4779 【模板】单源最短路径(标准版)
    洛谷 P1175 表达式的转换
    pipioj 1291 中缀表达式转后缀表达式I
  • 原文地址:https://www.cnblogs.com/sjqq/p/6842563.html
Copyright © 2020-2023  润新知