反射是一个程序集发现及运行的过程,通过反射可以得到*.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实例。

  1. namespace Project.Common
    {
    public class Factory
    {
    //记录dal的对象
    private static Hashtable dals;
    //用assemblyString记录DAL程序集的全名称
    private static string assemblyString = ConfigurationManager.AppSettings["LinqDAL"];
    private static Assembly assembly;
  2.  
  3. static Factory()
    {
    dals = new Hashtable();
    assembly = Assembly.Load(assemblyString);
    }
  4.  
  5. private static object CreateInstance(string typeName)
    {
    //当第一次加载时,将反射对象保存于dals集合里
    if (!dals.ContainsKey(typeName))
    {
    //创建反射对象
    object object1 = assembly.CreateInstance(typeName);
  6.  
  7. if (object1 == null)
    throw new Exception("未能创建此对象");
    //把对象加入dals集合
    dals["typeName"] = object1;
    }
    return dals["typeName"];
    }
  8.  
  9. public static IExampleDAL CreateExampleDAL()
    {
    return (IExampleDAL)CreateInstance(assemblyString + ".ExampleDAL");
    }
    }
  10.  
  11. class Program
    {
    //利用工厂模式生成对象
    static void Main(string[] args)
    {
    IExampleDAL iExampleDAL=Factory.CreateExampleDAL();
    .................
    Console.ReadKey();
    }
    }
    }
  12.  
  13. namespace Project.IDAL
    {
    public interface IExampleDAL
    {
    ///<summary>
    /// 插入Example行,若插入成功,则返回新增Example的行数
    ///</summary>
    ///<param name="example">Example对象</param>
    ///<returns>返回新增Example行数,默认值为-1</returns>
    int AddExample(Example example);
  14.  
  15. ///<summary>
    /// 更新Example表,Update成功返回已经更新的数据条数,失败返回-1
    ///</summary>
    ///<param name="example">Example对象</param>
    ///<returns>Update成功返回已经更新的数据条数,失败返回-1</returns>
    int UpdateExample(Example example);
  16.  
  17. ///<summary>
    /// 删除Example表中ID等于exampleID的行,返回已删除行数
    ///</summary>
    ///<param name="exampleID">Example对象的ID值</param>
    ///<returns>返回删除行数</returns>
    int DeleteExample(int exampleID);
  18.  
  19. ///<summary>
    /// 获取Example表的所有行
    ///</summary>
    ///<returns>返回Example表中的所有Example对象</returns>
    IList<Example> GetList();
  20.  
  21. ///<summary>
    /// 根据ID获取对应Example对象
    ///</summary>
    ///<param name="id"></param>
    ///<returns></returns>
    Example GetExampleByID(int id);
    }
    }
  22.  
  23. namespace Project.DAL
    {
    public class ExampleDAL:IExampleDAL
    {
    public int AddExample(Example example)
    {
    //实现AddExample方法
    ...........................
    }
    ..................................
    ..................................
    }
    }

.NET反射的更多相关文章

  1. 隐私泄露杀手锏 —— Flash 权限反射

    [简版:http://weibo.com/p/1001603881940380956046] 前言 一直以为该风险早已被重视,但最近无意中发现,仍有不少网站存在该缺陷,其中不乏一些常用的邮箱.社交网站 ...

  2. Java学习之反射机制及应用场景

    前言: 最近公司正在进行业务组件化进程,其中的路由实现用到了Java的反射机制,既然用到了就想着好好学习总结一下,其实无论是之前的EventBus 2.x版本还是Retrofit.早期的View注解框 ...

  3. 关于 CSS 反射倒影的研究思考

    原文地址:https://css-tricks.com/state-css-reflections 译者:nzbin 友情提示:由于演示 demo 的兼容性,推荐火狐浏览.该文章篇幅较长,内容庞杂,有 ...

  4. 编写高质量代码:改善Java程序的151个建议(第7章:泛型和反射___建议106~109)

    建议106:动态代理可以使代理模式更加灵活 Java的反射框架提供了动态代理(Dynamic Proxy)机制,允许在运行期对目标类生成代理,避免重复开发.我们知道一个静态代理是通过主题角色(Prox ...

  5. 运用Mono.Cecil 反射读取.NET程序集元数据

    CLR自带的反射机智和API可以很轻松的读取.NET程序集信息,但是不能对程序集进行修改.CLR提供的是只读的API,但是开源项目Mono.Cecil不仅仅可以读取.NET程序集的元数据,还可以进行修 ...

  6. .NET面试题系列[6] - 反射

    反射 - 定义,实例与优化 在面试中,通常会考察反射的定义(操作元数据),可以用反射做什么(获得程序集及其各个部件),反射有什么使用场景(ORM,序列化,反序列化,值类型比较等).如果答得好,还可能会 ...

  7. .NET基础拾遗(4)委托、事件、反射与特性

    Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...

  8. C++的性能C#的产能?! - .Net Native 系列五:.Net Native与反射

    此系列系小九的学堂原创翻译,翻译自微软官方开发向导,一共分为六个主题.本文是第五个主题:.Net Native与反射. 向导文链接:<C++的性能C#的产能?! - .Net Native 系列 ...

  9. [源码]Literacy 快速反射读写对象属性,字段

    Literacy 说明 Literacy使用IL指令生成方法委托,性能方面,在调用次数达到一定量的时候比反射高很多 当然,用IL指令生成一个方法也是有时间消耗的,所以在只使用一次或少数几次的情况,不但 ...

  10. SI与EMI(一) - 反射是怎样影响EMI

    Mark为期两天的EMC培训中大概分成四个时间差不多的部分,简单来说分别是SI.PI.回流.屏蔽.而在信号完整性的书籍中,也会把信号完整性分为:1.信号自身传输的问题(反射,损耗):2.信号与信号之间 ...

随机推荐

  1. Android自定义XML属性

    <?xml version="1.0" encoding="utf-8"?> <resources> <declare-style ...

  2. ubuntu12.04的NFS配置

    安装nfs: #sudo apt-get install nfs-kernel-server ubuntu12.04中的已经是最新版本了,无需安装 打开/etc/exports文件,在末尾加入: /h ...

  3. Java传参

    1.  如果参数是基本数据类型(int.long等),传值.方法内部改变参数值,外部值不变. 2.  如果参数是对象类型,传地址.方法内部改变对象值,外部对象值改变.但是,如果方法内部调用new重新构 ...

  4. HDU-1301 Jungle Roads(最小生成树[Prim])

    Jungle Roads Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total ...

  5. maven认识

    在这里普及一下知识: ┣ maven与ant是同类,构建工具 ┣ svn与cvs,css是同类,版本控制工具 1.为什么要用Maven? 在进行软件开发的过程中,无论什么项目,采用何种技术,使用何种编 ...

  6. ActionBar的简单使用

    只简单实现了一下ActionBar的使用,在右上角添加两个ActionBar,在左上角实现默认的返回箭头,类似于微信朋友圈的 这是MainActivity的代码: public class MainA ...

  7. Android Studio的使用(九)--设置IDE编码格式

    1.打开设置 2.勾选编码格式,在这里可以设置分别设置IDE.Project.File等级别的编码格式. 3.查看.修改各个文件的编码 4.当右击编辑界面时,可以直接设置当前文件的编码

  8. angular实现select的ng-options4

    ng实现简单的select <div ng-controller="ngSelect"> <select ng-model="vm.selectVal& ...

  9. 最新最全的html5标签集合

    最新最全的html5标签集合,按字母顺序排列的标签列表 4:指示在HTML4.01中定义了该元素 5:指示在HTML5中定义了该元素 标签 描述 <!--...--> 定义注释 <! ...

  10. 深入理解React、Redux

    深入理解React.ReduReact+Redux非常精炼,良好运用将发挥出极强劲的生产力.但最大的挑战来自于函数式编程(FP)范式.在工程化过程中,架构(顶层)设计将是一个巨大的挑战.要不然做出来的 ...