码迷,mamicode.com
首页 > 其他好文 > 详细

初识反射

时间:2018-07-12 16:38:26      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:核心   mem   总结   eth   获取值   void   eof   动态加载   default   

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

  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。

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

初识反射

标签:核心   mem   总结   eth   获取值   void   eof   动态加载   default   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!