• C#反射机制学习总结 .


    反射的定义:审查元数据并收集关于它的类型信息的能力。元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等。

    System.reflection命名空间包含的几个类,允许你反射(解析)这些元数据表的代码,如下所示:

    1. System.Reflection.Assembly   
    2. System.Reflection.MemberInfo  
    3. System.Reflection.EventInfo  
    4. System.Reflection.FieldInfo  
    5. System.Reflection.MethodBase  
    6. System.Reflection.ConstructorInfo  
    7. System.Reflection.MethodInfo  
    8. System.Reflection.PropertyInfo  
    9. System.Type  
    System.Reflection.Assembly 
    System.Reflection.MemberInfo
    System.Reflection.EventInfo
    System.Reflection.FieldInfo
    System.Reflection.MethodBase
    System.Reflection.ConstructorInfo
    System.Reflection.MethodInfo
    System.Reflection.PropertyInfo
    System.Type

    以下是上面几个类的使用方法:
    (1)使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。 
    (2)使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。 
    (3)使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetConstructors或 GetConstructor方法来调用特定的构造函数。 
    (4)使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetMethods或GetMethod方法来调用特定的方法。 
    (5)使用FiedInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。 
    (6)使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序。 
    (7)使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。 

    (8)使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等。

         

     反射的层次模型:

                          

     

    void Main  

    • {  
    •        //通过GetAssemblies 调用appDomain的所有程序集   
    •        foreach (Assembly assem in Appdomain.currentDomain.GetAssemblies())  
    •       {  
    •        //反射当前程序集的信息   
    •             reflector.ReflectOnAssembly(assem)  
    •       }  
    • }  
     
    static void Main
    {
           //通过GetAssemblies 调用appDomain的所有程序集
           foreach (Assembly assem in Appdomain.currentDomain.GetAssemblies())
          {
           //反射当前程序集的信息
                reflector.ReflectOnAssembly(assem)
          }
    }


    说明:调用AppDomain 对象的GetAssemblies 方法 将返回一个由System.Reflection.Assembly元素组成的数组。

     

     

    1. using system;  
    2. using sytem.reflection;  
    3. class reflecting   
    4. {  
    5.        static void Main(string[]args)  
    6.        {  
    7.              reflecting reflect=new reflecting();//定义一个新的自身类   
    8.              //调用一个reflecting.exe程序集   
    9.   
    10.              assembly myAssembly =assembly.loadfrom(“reflecting.exe”)  
    11.              reflect.getreflectioninfo(myAssembly);//获取反射信息   
    12.        }  
    13.   
    14.        //定义一个获取反射内容的方法   
    15.        void getreflectioninfo(assembly myassembly)  
    16.        {  
    17.              type[] typearr=myassemby.Gettypes();//获取类型   
    18.              foreach (type type in typearr)//针对每个类型获取详细信息   
    19.             {  
    20.                    //获取类型的结构信息   
    21.                   constructorinfo[] myconstructors=type.GetConstructors;  
    22.   
    23.                  //获取类型的字段信息   
    24.                  fieldinfo[] myfields=type.GetFiedls()  
    25.   
    26.                  //获取方法信息   
    27.                  MethodInfo   myMethodInfo=type.GetMethods();  
    28.   
    29.                  //获取属性信息   
    30.                  propertyInfo[] myproperties=type.GetProperties  
    31.   
    32.                  //获取事件信息   
    33.                  EventInfo[] Myevents=type.GetEvents;  
    34.            }  
    35.       }  
    36. }  
    using system;
    using sytem.reflection;
    class reflecting 
    {
           static void Main(string[]args)
           {
                 reflecting reflect=new reflecting();//定义一个新的自身类
                 //调用一个reflecting.exe程序集
    
                 assembly myAssembly =assembly.loadfrom(“reflecting.exe”)
                 reflect.getreflectioninfo(myAssembly);//获取反射信息
           }
    
           //定义一个获取反射内容的方法
           void getreflectioninfo(assembly myassembly)
           {
                 type[] typearr=myassemby.Gettypes();//获取类型
                 foreach (type type in typearr)//针对每个类型获取详细信息
                {
                       //获取类型的结构信息
                      constructorinfo[] myconstructors=type.GetConstructors;
    
                     //获取类型的字段信息
                     fieldinfo[] myfields=type.GetFiedls()
    
                     //获取方法信息
                     MethodInfo   myMethodInfo=type.GetMethods();
    
                     //获取属性信息
                     propertyInfo[] myproperties=type.GetProperties
    
                     //获取事件信息
                     EventInfo[] Myevents=type.GetEvents;
               }
          }
    }


    其它几种获取type对象的方法:
    1、System.type   参数为字符串类型,该字符串必须指定类型的完整名称(包括其命名空间)
    2、System.type 提供了两个实例方法:GetNestedType,GetNestedTypes
    3、Syetem.Reflection.Assembly 类型提供的实例方法是:GetType,GetTypes,GetExporedTypes
    4、System.Reflection.Moudle 提供了这些实例方法:GetType,GetTypes,FindTypes

     

    设置反射类型的成员:
    反射类型的成员就是反射层次模型中最下面的一层数据。我们可以通过type对象的GetMembers 方法取得一个类型的成员。如果我们使用的是不带参数的GetMembers,它只返回该类型的公共定义的静态变量和实例成员,我们也可以通过使用带参数的 GetMembers通过参数设置来返回指定的类型成员。具体参数参考msdn 中system.reflection.bindingflags 枚举类型的详细说明。

    例如:

     

    1. //设置需要返回的类型的成员内容   
    2. bindingFlags bf=bingdingFlags.DeclaredOnly|bingdingFlags.Nonpublic|BingdingFlags.Public;  
    3. foreach (MemberInfo mi int t.getmembers(bf))  
    4. {  
    5.        writeline(mi.membertype)    //输出指定的类型成员   
    6. }  
    //设置需要返回的类型的成员内容
    bindingFlags bf=bingdingFlags.DeclaredOnly|bingdingFlags.Nonpublic|BingdingFlags.Public;
    foreach (MemberInfo mi int t.getmembers(bf))
    {
           writeline(mi.membertype)    //输出指定的类型成员
    }

     

     

    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Text;  
    4. using System.Text.RegularExpressions;  
    5. using System.Web.UI;  
    6. using System.Collections;  
    7. namespace cn.SwordYang  
    8. {  
    9.     public class TextClass:System.Web.UI.Page  
    10.     {  
    11. public static void RunJs(Page _page, string Source)  
    12.         {  
    13.             _page.ClientScript.RegisterStartupScript(_page.GetType(), "", "<script type="text/javascript">" + Source + ";</script>");  
    14.         }  
    15. }  
    16. }  
    17. //调用代码   
    18. System.Reflection.Assembly ass = Assembly.LoadFrom(Server.MapPath("bin/swordyang.dll")); //加载DLL   
    19.             System.Type t = ass.GetType("cn.SwordYang.TextClass");//获得类型   
    20.             object o = System.Activator.CreateInstance(t);//创建实例   
    21.             System.Reflection.MethodInfo mi = t.GetMethod("RunJs");//获得方法   
    22.             mi.Invoke(o, new object[] { this.Page,"alert('测试反射机制')"});//调用方法  
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Web.UI;
    using System.Collections;
    namespace cn.SwordYang
    {
        public class TextClass:System.Web.UI.Page
        {
    public static void RunJs(Page _page, string Source)
            {
                _page.ClientScript.RegisterStartupScript(_page.GetType(), "", "<script type="text/javascript">" + Source + ";</script>");
            }
    }
    }
    //调用代码
    System.Reflection.Assembly ass = Assembly.LoadFrom(Server.MapPath("bin/swordyang.dll")); //加载DLL
                System.Type t = ass.GetType("cn.SwordYang.TextClass");//获得类型
                object o = System.Activator.CreateInstance(t);//创建实例
                System.Reflection.MethodInfo mi = t.GetMethod("RunJs");//获得方法
                mi.Invoke(o, new object[] { this.Page,"alert('测试反射机制')"});//调用方法


    反射机制对应设计模式中的策略模式。

  • 相关阅读:
    C# GDI 绘图打印
    使用批处理,WINRAR 创建自解压文件
    c# 开放/封闭原则
    php 盖尔-沙普利算法
    c# 遍历 Mysql 所有表所有列,查找目标数据
    C# 与 C++ 互操作(C# 调用 C++ 的动态链接库)
    c# WPF DataGrid 获取选中单元格信息
    c# WPF SVG 文件的引用(SharpVectors)
    c# 使用网站的身份验证及 Cookie 的获取与使用
    c# HttpListener 使用
  • 原文地址:https://www.cnblogs.com/tdskee/p/3897479.html
Copyright © 2020-2023  润新知