撸·反射

反射是一个程序集发现及运行的过程,经过反射能够获得*.exe或*.dll等程序集内部的信息。使用反射能够看到一个程序集内部的接口、类、方法、字段、属性、特性等等信息。在System.Reflection命名空间内包含多个反射经常使用的类。如下是基础

常见反射类html

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

1、System.Reflection.Assembly类

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

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

利用Assembly的object CreateInstance(string) 方法能够反射建立一个对象,参数为类名。spa

2、System.Type类

  Type是最经常使用到的类,经过Type能够获得一个类的内部信息,也能够经过它反射建立一个对象。通常有三个经常使用的方法可获得Type对象。code

  1. 利用typeof() 获得Type对象
Type type=typeof(Example);
  1. 利用System.Object.GetType() 获得Type对象
Example example=new Example();
Type type=example.GetType();
  1. 利用System.Type.GetType() 获得Type对象
Type type=Type.GetType("MyAssembly.Example",false,true);

注意第一个参数是类名,第二个参数表示若找不到对应类时是否抛出异常,第三个参数表示类名是否区分大小写。htm

例子:
咱们最多见的是利用反射与Activator结合来建立对象。对象

Assembly assembly= Assembly.Load("MyAssembly");
   Type type=assembly.GetType("Example");
   object obj=Activator.CreateInstance(type);

3、反射方法

  1. 经过 System.Reflection.MethodInfo能查找到类里面的方法。
    代码:
Type type=typeof(Example);
    MethodInfo[] listMethodInfo=type.GetMethods();
    foreach(MethodInfo methodInfo in listMethodInfo)
    Cosole.WriteLine("Method name is "+methodInfo.Name);
  1. 咱们也能经过反射方法执行类里面的方法。
    代码:
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);  //第二个参数类型为object[],表明Hello World方法的对应参数,输入值为null表明没有参数。

4、反射属性

  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);
  1. 咱们也能够经过如下方法设置或者获取一个对象的属性值
    代码:
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

5、反射字段

经过 System.Reflection.FieldInfo 能查找到类里面的字段
它包括有两个经常使用方法SetValue(object ,object )和GetValue(object) 由于使用方法与反射属性很是类似,在此再也不多做介绍。
(略)blog

6、反射特性

经过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());

7、经常使用实例

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

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方法
        }      
    }
}

总结

本篇文章转载于 风尘浪子的《反射的奥妙

相关文章
相关标签/搜索