当前位置: 首页 > news >正文

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


上面只是介绍了反射的基本用法,当然反射还有很多其他用途,下面几篇文章将为大家一一介绍

 

 

.NET基础篇

以异步的方式操作TCP/IP套接字——以异步方式实现简单的聊天室 合理使用“.NET扩展方法”来简化代码(例子:空值判断,利用扩展方法实现LINQ操作符ForEach) 分部类和分部方法 反射的奥妙 利用泛型与反射更新实体(ADO.NET Entity Framework)

 

作者:风尘浪子

http://www.cnblogs.com/leslies2/archive/2011/11/22/2257703.html

原创作品,转载时请注明作者及出处

 

 

 

 

转载于:https://www.cnblogs.com/leslies2/archive/2011/11/22/2257703.html

相关文章:

  • ElasticSearch实战-日志监控平台
  • WP7 开发(十四) ApplicationBar
  • Linux下搭建svn服务器
  • nodejs的一些局限
  • 操作无法完成。键入的打印机名不正确,或者指定的打印机没有连接到服务器上...
  • 红黑树源码及错误解析
  • 修复垂直滑动RecyclerView嵌套水平滑动RecyclerView水平滑动不灵敏问题
  • 无线网络覆盖 郑州大学第三届acm比赛试题 n 199
  • 回数
  • 生成备案号例如80-027-1-001 规则为:企业编号-所在区号-产品类别-序号
  • 颠覆你的认知,带你领略史上最为齐全的微软黑科技之旅
  • 时代杂志评年度十大科技产品 iPad 2居首
  • 成功恢复FAT32误格式化后所有碎片文件(已覆盖的除外)
  • maya羽毛制作插件
  • 如何使用sendEmail发送邮件
  • 【391天】每日项目总结系列128(2018.03.03)
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • Android交互
  • Apache的80端口被占用以及访问时报错403
  • eclipse(luna)创建web工程
  • js操作时间(持续更新)
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • Python进阶细节
  • Vue ES6 Jade Scss Webpack Gulp
  • vuex 笔记整理
  • webpack入门学习手记(二)
  • 开发基于以太坊智能合约的DApp
  • 小程序 setData 学问多
  • ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
  • #在线报价接单​再坚持一下 明天是真的周六.出现货 实单来谈
  • (12)Hive调优——count distinct去重优化
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (完整代码)R语言中利用SVM-RFE机器学习算法筛选关键因子
  • (转)ABI是什么
  • (转)nsfocus-绿盟科技笔试题目
  • (轉貼) 蒼井そら挑戰筋肉擂台 (Misc)
  • (轉貼) 寄發紅帖基本原則(教育部禮儀司頒布) (雜項)
  • .class文件转换.java_从一个class文件深入理解Java字节码结构
  • .NET delegate 委托 、 Event 事件
  • .NET 中 GetHashCode 的哈希值有多大概率会相同(哈希碰撞)
  • .net 中viewstate的原理和使用
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • .NET委托:一个关于C#的睡前故事
  • // an array of int
  • @Autowired自动装配
  • [BUUCTF NewStarCTF 2023 公开赛道] week4 crypto/pwn
  • [bzoj 3534][Sdoi2014] 重建
  • [CISCN 2019华东南]Web11
  • [HCTF 2018]WarmUp (代码审计)
  • [IE9] GPU硬件加速到底是实用创新还是噱头
  • [Java][算法 双指针]Day 02---LeetCode 热题 100---04~07
  • [Linux] Ubuntu install Miniconda
  • [Linux]进程间通信(system V共享内存 | system V信号量)
  • [POI2006] OKR-Periods of Words——最大周期长度(扩展最小周期长度)
  • [Python]Selenium-自动化测试