• .NET反射


    反射是一个程序集发现及运行的过程,通过反射可以得到*.exe或*.dll等程序集内部的信息。使用反射可以看到一个程序集内部的接口、类、方法、字段、属性、特性等等信息。在System.Reflection命名空间内包含多个反射常用的类,下面表格列出了常用的几个类。

    类型 作用
    Assembly 通过此类可以加载操纵一个程序集,并获取程序集内部信息
    EventInfo 该类保存给定的事件信息
    FieldInfo 该类保存给定的字段信息
    MethodInfo 该类保存给定的方法信息
    MemberInfo 该类是一个基类,它定义了EventInfo、FieldInfo、MethodInfo、PropertyInfo的多个公用行为
    Module 该类可以使你能访问多个程序集中的给定模块
    ParameterInfo 该类保存给定的参数信息      
    PropertyInfo 该类保存给定的属性信息

    一、System.Reflection.Assembly类

         通过Assembly可以动态加载程序集,并查看程序集的内部信息,其中最常用的就是Load()这个方法。

         Assembly assembly=Assembly.Load("MyAssembly");

         利用Assembly的object CreateInstance(string) 方法可以反射创建一个对象,参数0为类名。

    二、System.Type类

         Type是最常用到的类,通过Type可以得到一个类的内部信息,也可以通过它反射创建一个对象。一般有三个常用的方法可得到Type对象。

    1. 利用typeof() 得到Type对象

      Type type=typeof(Example);

    2. 利用System.Object.GetType() 得到Type对象

      Example example=new Example();

      Type type=example.GetType();

    3. 利用System.Type.GetType() 得到Type对象

      Type type=Type.GetType("MyAssembly.Example",false,true);

      注意参数0是类名,参数1表示若找不到对应类时是否抛出异常,参数1表示类名是否区分大小写

       例子:

       我们最常见的是利用反射与Activator结合来创建对象。

       Assembly assembly= Assembly.Load("MyAssembly");

       Type type=assembly.GetType("Example");

       object obj=Activator.CreateInstance(type);

        

    三、反射方法

        1.通过 System.Reflection.MethodInfo能查找到类里面的方法

        代码:

        Type type=typeof(Example);

        MethodInfo[] listMethodInfo=type.GetMethods();

        foreach(MethodInfo methodInfo in listMethodInfo)

             Cosole.WriteLine("Method name is "+methodInfo.Name);

      

       2.我们也能通过反射方法执行类里面的方法

       代码:

       Assembly assembly= Assembly.Load("MyAssembly");

       Type type=assembly.GetType("Example");

       object obj=Activator.CreateInstance(type);

       MethodInfo methodInfo=type.GetMethod("Hello World");  //根据方法名获取MethodInfo对象

       methodInfo.Invoke(obj,null);  //参数1类型为object[],代表Hello World方法的对应参数,输入值为null代表没有参数

    四、反射属性

       1.通过 System.Reflection.PropertyInfo 能查找到类里面的属性

         常用的方法有GetValue(object,object[]) 获取属性值和 SetValue(object,object,object[]) 设置属性值

       代码:

        Type type=typeof(Example);

        PropertyInfo[] listPropertyInfo=type.GetProperties();

        foreach(PropertyInfo propertyInfo in listPropertyInfo)

             Cosole.WriteLine("Property name is "+ propertyInfo.Name);

       

       2.我们也可以通过以下方法设置或者获取一个对象的属性值

       代码:

       Assembly assembly=Assembly.Load("MyAssembly");

       Type type=assembly.GetType("Example");

       object obj=Activator.CreateInstance(type);

       PropertyInfo propertyInfo=obj.GetProperty("Name");    //获取Name属性对象

       var name=propertyInfo.GetValue(obj,null);                //获取Name属性的值

       PropertyInfo propertyInfo2=obj.GetProperty("Age");     //获取Age属性对象

       propertyInfo.SetValue(obj,34,null);                              //把Age属性设置为34

    五、反射字段

        通过 System.Reflection.FieldInfo 能查找到类里面的字段

        它包括有两个常用方法SetValue(object ,object )和GetValue(object)  因为使用方法与反射属性非常相似,在此不再多作介绍

       (略)

    六、反射特性

       通过System.Reflection.MemberInfo的GetCustomAttributes(Type,bool)就可反射出一个类里面的特性,以下例子可以反射出一个类的所有特性

       代码:

       Type type=typeof("Example");

       object[] typeAttributes=type.GetCustomAttributes(false);       //获取Example类的特性

       foreach(object attribute in typeAttributes)

             Console.WriteLine("Attributes description is "+attribute.ToString());

      

       通过下面例子,可以获取Example类Name属性的所有特性

       代码:

       public class Example

       {

             [DataMemberAttribute]

             publics string Name

              {get;set;}

            ..................

        }

        Type type = typeof(Example);       
        PropertyInfo propertyInfo=type.GetProperty("Name");    //获取Example类的Name属性
        foreach (object attribute in propertyInfo.GetCustomAttributes(false))        //遍历Name属性的所有特性
               Console.WriteLine(“Property attribute: "+attribute.ToString());

    七、常用实例

        虽然反射有很多奥妙之处,但要注意使用反射生成对象会耗费很多性能,所能必须了解反射的特性,在合适的地方使用。最常见例子就是利用单体模式与反射一并使用,  在BLL调用DAL的时候,通过一个反射工厂生成DAL实例。

    复制代码
    namespace Project.Common
    {
    public class Factory
    {
    //记录dal的对象
    private static Hashtable dals;
    //用assemblyString记录DAL程序集的全名称
    private static string assemblyString = ConfigurationManager.AppSettings["LinqDAL"];
    private static Assembly assembly;

    static Factory()
    {
    dals = new Hashtable();
    assembly = Assembly.Load(assemblyString);
    }

    private static object CreateInstance(string typeName)
    {
    //当第一次加载时,将反射对象保存于dals集合里
    if (!dals.ContainsKey(typeName))
    {
    //创建反射对象
    object object1 = assembly.CreateInstance(typeName);

    if (object1 == null)
    throw new Exception("未能创建此对象");
    //把对象加入dals集合
    dals["typeName"] = object1;
    }
    return dals["typeName"];
    }

    public static IExampleDAL CreateExampleDAL()
    {
    return (IExampleDAL)CreateInstance(assemblyString + ".ExampleDAL");
    }
    }

    class Program
    {
    //利用工厂模式生成对象
    static void Main(string[] args)
    {
    IExampleDAL iExampleDAL=Factory.CreateExampleDAL();
    .................
    Console.ReadKey();
    }
    }
    }

    namespace Project.IDAL
    {
    public interface IExampleDAL
    {
    ///<summary>
    /// 插入Example行,若插入成功,则返回新增Example的行数
    ///</summary>
    ///<param name="example">Example对象</param>
    ///<returns>返回新增Example行数,默认值为-1</returns>
    int AddExample(Example example);

    ///<summary>
    /// 更新Example表,Update成功返回已经更新的数据条数,失败返回-1
    ///</summary>
    ///<param name="example">Example对象</param>
    ///<returns>Update成功返回已经更新的数据条数,失败返回-1</returns>
    int UpdateExample(Example example);

    ///<summary>
    /// 删除Example表中ID等于exampleID的行,返回已删除行数
    ///</summary>
    ///<param name="exampleID">Example对象的ID值</param>
    ///<returns>返回删除行数</returns>
    int DeleteExample(int exampleID);

    ///<summary>
    /// 获取Example表的所有行
    ///</summary>
    ///<returns>返回Example表中的所有Example对象</returns>
    IList<Example> GetList();

    ///<summary>
    /// 根据ID获取对应Example对象
    ///</summary>
    ///<param name="id"></param>
    ///<returns></returns>
    Example GetExampleByID(int id);
    }
    }

    namespace Project.DAL
    {
    public class ExampleDAL:IExampleDAL
    {
    public int AddExample(Example example)
    {
    //实现AddExample方法
    ...........................
    }
    ..................................
    ..................................
    }
    }
    复制代码
  • 相关阅读:
    1052 Linked List Sorting (25 分)
    1051 Pop Sequence (25 分)
    1050 String Subtraction (20 分)
    1049 Counting Ones (30 分)
    1048 Find Coins (25 分)
    1047 Student List for Course (25 分)
    1046 Shortest Distance (20 分)
    1045 Favorite Color Stripe (30 分)
    1044 Shopping in Mars (25 分)
    1055 The World's Richest (25 分)
  • 原文地址:https://www.cnblogs.com/tiancai/p/6050689.html
Copyright © 2020-2023  润新知