C#综合揭秘——反射的奥妙

简介:

C#综合揭秘——反射的奥妙

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

上面只是介绍了反射的基本用法,当然反射还有很多其他用途,下面几篇文章将为大家一一介绍
 
C#综合揭秘
以异步的方式操作TCP/IP套接字——以异步方式实现简单的聊天室 合理使用“.NET扩展方法”来简化代码(例子:空值判断,利用扩展方法实现LINQ操作符ForEach) 分部类和分部方法 反射的奥妙 利用泛型与反射更新实体(ADO.NET Entity Framework)
对JAVA与.NET开发有兴趣的朋友欢迎加入QQ群:162338858  点击这里加入此群
出处:http://79100812.blog.51cto.com/
作者:风尘浪子
原创作品,转载时请注明作者及出处
 


 


本文转自 leslies2  51CTO博客,原文链接:http://blog.51cto.com/79100812/727722
相关文章
|
3月前
|
设计模式 C#
C#反射机制实现开闭原则的简单工厂模式
C#反射机制实现开闭原则的简单工厂模式
18 0
|
4月前
|
存储 C# 开发者
C# | 通过反射将对象属性展示在TreeView中
在编程过程中,我们经常需要处理复杂的对象和数据结构。将这些数据结构展示在UI界面上是很有用的,可以帮助开发者更好地理解和分析数据。 而TreeView作为一种常见的控件,可以以树状结构的方式展示数据,非常适合用于展示层次化的对象。 本文将介绍如何使用TreeView控件展示一个对象,并且可以动态处理对象中的属性和子对象。通过本文的学习,您将学会如何更好地理解和展示数据,提高编程效率。
34 0
C# | 通过反射将对象属性展示在TreeView中
|
4月前
|
安全 C# 图形学
C#的反射机制
C#的反射机制
|
5月前
|
存储 Java API
C#反射(Reflection)详解
反射是.NET中的重要机制,通过反射可以得到*.exe或*.dll等程序集内部的接口、类、方法、字段、属性、特性等信息,还可以动态创建出类型实例并执行其中的方法。反射指程序可以访问、检测和修改它本身状态或行为的一种能力。通俗一点:我们在获取其他实体类的字段名或实列,只能获取公有的,而有了反射之后可以获取私有的,可以获取他的基类等等,可以说把家底查得清清楚楚。
31 1
|
7月前
|
开发框架 缓存 安全
C#OOP之十三 组件、程序集与反射
C#OOP之十三 组件、程序集与反射
38 0
|
7月前
|
开发框架 .NET Java
C#下反射动态加载dll后如何卸载?
C#下反射动态加载dll后如何卸载?
|
7月前
|
Oracle 架构师 关系型数据库
C#反射应用之实现动态可配置可扩展框架的简单示例
C#反射应用之实现动态可配置可扩展框架的简单示例
|
7月前
|
Java 关系型数据库 MySQL
C#反射(Reflection)详解及于java反射的对比
C#反射(Reflection)详解及于java反射的对比
|
9月前
|
C# 数据安全/隐私保护
C#机房重构-修改密码之职责链模式+反射
C#机房重构-修改密码之职责链模式+反射
42 0
|
10月前
|
运维 Devops C#
【C#编程最佳实践 十七】反射工厂最佳实践
【C#编程最佳实践 十七】反射工厂最佳实践
58 0