初识反射

一:什么是反射?反射能干什么?

  1.反射是一种能力,所以给的定义就是说明了它能干什么

  2.获取类型相关的信息;动态的调用方法;动态构造对象;从程序集中获得类型

    a:获取类型相关的信息:反射的核心Type类,Type对象提供的属性和方法可以获取对象的一切信息(方法,字段,属性,事件);

直接使用typeof操作符 Type T1 = typeof(StringBuilder);

      通过类型实例 Type T2 = new StringBuilder().GetType();

      通过Type类的静态方法 Type T3 = Type.GetType("System.IO.Stream");

    b:获取类型本身信息(命名空间,全名,是否是抽象,是否是类)

     var T1 = typeof(StringBuilder);

     Console.WriteLine("命名空间名称:"+T1.Namespace);

     Console.WriteLine("直接基类型",T1.BaseType);

       Console.WriteLine("全名",T1.FullName);

     Console.WriteLine("是否是抽象类型",T1.IsAbstract);

        Console.WriteLine("是类",T1.IsClass);

      

    c:获取类型成员的信息

     Type T1 = typeof(TClass);

     var Mets = T1.GetMembers();

     foreach(var m in Mets)

     {

        Console.WriteLine(m.MemberType()+":"+m.Name);
     }

  

    d:动态调用方法:

     首先自定义一个类

     public class TClass
     {

        public void fun(string str)

        {

          Cosole.WriteLine("我是fun方法,我被调用了",str);
        }

        public void fun2()
        {

          Console.WriteLine("我是fun2方法,我被调用了");
        }

        public void static fun3()
        {

          Console.WriteLine("我是fun3方法,我被调用了");
        }
     }

      A:调用方式一(使用InvokeMember调用方法)

      调用带参数的实例方法fun()

        Type T1 = typeof(TClass);

      T1.InvokeMember("fun",BindingFlags.InvokeMethod,null,new TClass(),new string[]{"test"});

      

     调用无参数实例方法fun2()

     Type T1 = typeof(TClass);

     T1.InvokeMember("fun3",BindingFlags.InvokeMethod,null,new TClass(),null);

     调用静态方法

     Type T1 = typeof(TClass);

     T1.InvokeMember("fun3",BindingFlags.InvokeMethod,null,T1,null);  

      注意:当我们调用实例方法的时候需要传实例对象过去。在我们实例了对象后,任然不确定调用哪个方法时可以只有使用,

        如果实例对象也不确定,接着往下看

     第一个:要被动态调用的方法名。

     第二个:是一个枚举,表示调用一个方法

     第三个:是Binder,传的是null,使用默认值。

     第四个:传如实例对象(调用实例方法时)或者Type对象(调用静态方法时)

     第五个:要传给被调用发的参数数组

      B:调用方式二(使用MethodInfo.Invoke调用方法)

     Type T1 = typeof(TClass);

     T1.GetMethod("fun",BindingFlags.Instance|BindingFlages.Public).Invoke(new TClass(),new string[]{"testfun1"});         

     T1.GetMethod("fun2",BindingFlags.Instance|BindingFlages.Public).Invoke(new TClass(),null);

     T1.GetMethod("fun3",BindingFlags.Static|BindingFlages.Public).Invoke(T1,null);

     

    C:正真的全动态调用

       Console.WriteLine("请输入对象类名");

     string className = Console.ReadLine();

     Console.WriteLine("请输入要执行的方法名");

     string funName = Console.ReadLine();

     Type T1 = Type.GetType(className);

     ConstructorInfo ci = T1.GetConstructors()[0]; //获取构造函数

     var obj = ci.Invoke(null);          //实例化构造函数

     T1.InvokeMember(funName,BindingFlags.InvokeMethod,null,obj,null);

      

      d:动态构造对象

      先定义一个对象

      public class TClass

      {

          public TClass()
        {

          Console.WriteLine("构造函数被执行了");
        }  

        public TClass(string str)
        {

          Console.WriteLine("有参数的构造函数被执行了"+str);
        }
      }

    动态构造对象

    //动态构造对象,方式一

    Assembly as, = Assembly.GetExecutingAssembly();    

    TClass obj = (TClass).asm.CreateInstance("net.tclass",true);  

    //动态构造对象,方式二

    ObjectHandle handler = Activator.CreateInstance(null,"net.TClass");

    obj = (TClass)handler.Unwrap();

    //动态构造函数,方式三

    Assembly asm2 = Assembly.GetExecutingAssembly();

    obj = (TClass)asm2.CreateInstance("net.tclass",true,BindingFlages.Default,null,new string[]{"test"},null,null);

    

    获取和修改属性  

    var obj = new TClass();
    obj.name = "张三";
    Type type = typeof(TClass);
    //获取属性
    var Name = type.InvokeMember("name", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, null,
    obj, new object[] { }) as string;
    Console.WriteLine(obj.name);
    //设置属性
    type.InvokeMember("name", BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance, null,
    obj, new object[] { "新属性(李四)" });
    Console.WriteLine(obj.name);

    //=====================

    PropertyInfo[] pros = type.GetProperties(---);//
    PropertyInfo pro = null;

    var value = pro.GetValue(type);//获取值

    

    e:从程序集里获得类型

    取得当前代码所在程序集

    Assembly ass = Assembly.GetExecutingAssembly();

    Console.WriteLine("当前所在程序集名:"+ass.ManifestModule.Name);

    Console.WriteLine("当前所在程序集路径:"+ass.Location);

     

  

    总结:反射不是某一个概念,而是一类操作的统称。或者说是某些能力的统称,它能动态调用对象方法,动态读取和设置属性和字段,它能动态加载程序外的dll。

    看你想要什么样的薪资。(和工作年限无关)
    如果要月薪五位数的话,反射、多线程、委托事件、设计模式一般都会在面试的时候问到。
    就算不一定每次面试都会问到,那也是你必须要知道的。

原文地址:https://www.cnblogs.com/HansZimmer/p/9299380.html

时间: 2024-11-10 13:53:28

初识反射的相关文章

1 初识反射

一提起反射这个概念 很多人都害怕.既然java只学过类这个东西,怎么还会说类也是一个对象呢? 先写三个类(伪代码) 学生类 { 姓名 年龄 性别 吃饭(); 睡觉(); 读书(); } 动物类 { 名称: 性别: 栖息地: 吼叫(); 交配(); } 书本类 { 颜色 价格 书名 打开() 关闭( ) } 如果我们要一本书 那么就new 书本()   要个学生new 学生()   书本类是对所有图书共性的描述 动物类是对所有动物共性的描述 我们这样做,我认为叫正射. 我们的思想是这样的  有了一

初识反射之二

上一篇说了反射的三种方式.今天就第三种说一说Class.forName("这个类的全程").这个是动态加载.加载机制里面有一个动态加载和静态加载. 先说静态加载,就相当于万事俱备只欠东风型,怎么说呢?他会把你写的代码每个都检查一遍,都通过了才能进行运行. 动态加载就显得灵活一些,相当于吃自助,就是需要什么加载什么,其他不需要的哪怕出错,那先不管. 然后再说这个Class.forName("这个类的全称") ,它相当于把这个神仙对象弄出来了.可是当调用newstanc

初识反射之三(获取方法和成员变量)

当你还是一个对象时,你通过了修仙,getClass()方法得道成仙,然后开心的当上了神仙.然后发现神仙也有很多种,赤脚大仙,风神电母.那么你是不是好奇曾经仰望的神仙(类)会有什么技能(方法)和名字呢?这就是这篇我们应该讨论的.哈哈哈! 万物皆对象.类和方法也是对象. 然后通过方法.通过 getMethods() 获得了里面的方法.而方法里面还有 你能看到人家自己声明的方法以及全部方法. 再细分的话,方法不是有返回值吗?还有参数嘛.这些都可以用方法获得,不过是得到的就是数组了.getRurnTyp

初识JAVA反射<一>_0626

反射 一.最开始接触javaSE的时候就没有怎么学过反射,感觉好难,老师讲的也很晦涩,然后就没有然后了,最近项目中用到了AOP切面编程,全都是运用的反射,不学不行了,索性问问过来人. 1.一种说法是java反射实际上就是转换,讲java代码转换为二进制. 2.第二种说法就是将javaBean什么的转换成你需要的形式. 现在给我的想法,我觉得在SpingMVC上就用到了反射,我前台的ajax传过来的值,可以直接传到我的Controller的参数中得类,比如说, $.ajax{ .... data:

初识JAVA(【面向对象】:pub/fri/pro/pri、封装/继承/多态、接口/抽象类、静态方法和抽象方法;泛型、垃圾回收机制、反射和RTTI)

JAVA特点: 语法简单,学习容易 功能强大,适合各种应用开发:J2SE/J2ME/J2EE 面向对象,易扩展,易维护 容错机制好,在内存不够时仍能不崩溃.不死机 强大的网络应用功能 跨平台:JVM,字节码 两个命令: javac helloworld.java:将Java文件编译为字节码的.class文件 java helloworld:运行Java程序...??暂时这么认为 数据类型: 普通数据类型:int a=3; 对象数据类型:使用关键字new,String s=new String("

初识java反射机制

反射是动态性最大的体现 运行时才能改变编译期所确定的效果是编程语言的动态性. java动态性可以利用反射机制探究使用编译期未知的类 ,java反射计数是java程序的特征之一 它允许运行中的java程序对自身进行检查或者自审并能直接操作程序的内部属性 在一般的设计应用中使用步骤:一是获得要操作的类的class对象 二是探究class类中的信息(属性  构造  方法) 三是使用class对象中的信息如:使用构造产生对象的实例对象‘   使用属性的get/set方法   方法的调用等等 在反射机制里

learn_Day14 内置函数补充、反射、初识面向对象

内置函数 __import__()用于导入模块 getattr 用于寻找模块的指定对象 a = __import__('b')  # b为模块名,b是字符串 ==>> 导入模块b并重新命名为a c = getattr(a,'d')  # d为模块中指定对象 ==>> 找到模块中命名为d的对象 d() ==>> 执行d # getattr(a,'b', c) # 从a模块中导入b.c参数可不写表示找不到报错:c为None表示找不到不报错,返回None. # hasattr

初识Java反射

要详细的了解Java反射,就得要了解Java的类加载以及何为运行时动态加载等等概念.本文抛开其余概念,简单介绍Java反射,详细介绍会在以后有一个系统而全面的认识过后展开. 反射是Java被视为动态语言的关键,它允许程序在运行时取得任何类的内部信息.Java的这个能力或许在Web应用中用得不是很多,但在一些Java组件开发过程中非常常见,比如Spring.Hibernate等都以此为基础.了解并熟知Java反射机制对我们了解Java框架有很大的帮助. 我们首先写好一个Test类,并将它编译为cl

反射初识

使用反射可以调用其他程序集里面的方法,私有方法也可以调出,但是一般都使用的接口+反射的形式去调用类似以下例子: 接口: public interface SayMethod { void sayHello(); } 中国人说话的方法实现这个接口: public class Say : SayMethod { public void sayHello() { Console.WriteLine("你好"); } } 方法和类库分别都是单独的类库,生成后得到DLL文件在引用的时候反射的方法