c# 反射的应用

本文详细介绍了C#中的反射机制,包括如何获取类型信息、动态创建对象、调用方法以及委托的动态创建。同时探讨了反射的优点(灵活性、降低耦合)和缺点(性能损失、维护复杂性)。
摘要由CSDN通过智能技术生成

简述

反射指程序可以访问、检测和修改它本身状态或行为的一种能力。

程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对象。

您可以使用使用反射获取类型,根据类型来动态创建对象,可以获取方法以及动态调用方法,可以动态创建委托。然后,可以调用类型的方法或访问其字段和属性。
扩展:
如何使用反射获取类型
首先我们来看如何获得类型信息。
获得类型信息有两种方法,一种是得到实例对象
这个时侯我仅仅是得到这个实例对象,得到的方式也许是一个object的引用,也许是一个接口的引用,但是我并不知道它的确切类型,我需要了解,那么就可以通过调用System.Object上声明的方法GetType来获取实例对象的类型对象,比如在某个方法内,我需要判断传递进来的参数是否实现了某个接口,如果实现了,则调用该接口的一个方法:

public  void  Process(  object  processObj  )
{
Type  t  =  processsObj.GetType();
if(  t.GetInterface(“ITest”)  !=null  )}

另外一种获取类型的方法是通过Type.GetType以及Assembly.GetType方法,如:
Type t = Type.GetType(“System.String”);
需要注意的是,前面我们讲到了命名空间和装配件的关系,要查找一个类,必须指定它所在的装配件,或者在已经获得的Assembly实例上面调用GetType。

如何根据类型来动态创建对象
System.Activator提供了方法来根据类型动态创建对象,比如创建一个DataTable:

Type  t  =  Type.GetType("System.Data.DataTable,System.Data,Version=1.0.3300.0,  Culture=neutral,  PublicKeyToken=b77a5c561934e089");
DataTable  table  =  (DataTable)Activator.CreateInstance(t);

例二:根据有参数的构造器创建对象

namespace  TestSpace  
{
  public  class  TestClass
      {
      private  string  _value;
      public  TestClass(string  value)  
    {
      _value=value;
      }
  }
}Type  t  =  Type.GetType(“TestSpace.TestClass”);
Object[]  constructParms  =  new  object[]  {“hello”};  //构造器参数
TestClass  obj  =  (TestClass)Activator.CreateInstance(t,constructParms);

把参数按照顺序放入一个Object数组中即可
如何获取方法以及动态调用方法


namespace  TestSpace
{
      public  class  TestClass  {
          private  string  _value;
          public  TestClass()  {
          }
          public  TestClass(string  value)  {
                _value  =  value;
          }
          public  string  GetValue(  string  prefix  )  {
          if(  _value==null  )
          return  "NULL";
          else
            return  prefix+"  :  "+_value;
            }
            public  string  Value  {
set  {
_value=value;
}
get  {
if(  _value==null  )
return  "NULL";
else
return  _value;
}
            }
      }
}

上面是一个简单的类,包含一个有参数的构造器,一个GetValue的方法,一个Value属性,我们可以通过方法的名称来得到方法并且调用之,如:


//获取类型信息
Type  t  =  Type.GetType("TestSpace.TestClass");
//构造器的参数
object[]  constuctParms  =  new  object[]{"timmy"};
//根据类型创建对象
object  dObj  =  Activator.CreateInstance(t,constuctParms);
//获取方法的信息
MethodInfo  method  =  t.GetMethod("GetValue");
//调用方法的一些标志位,这里的含义是Public并且是实例方法,这也是默认的值
BindingFlags  flag  =  BindingFlags.Public  |  BindingFlags.Instance;
//GetValue方法的参数
object[]  parameters  =  new  object[]{"Hello"};
//调用方法,用一个object接收返回值
object  returnValue  =  method.Invoke(dObj,flag,Type.DefaultBinder,parameters,null);

动态创建委托
委托是C#中实现事件的基础,有时候不可避免的要动态的创建委托,实际上委托也是一种类型:System.Delegate,所有的委托都是从这个类派生的
System.Delegate提供了一些静态方法来动态创建一个委托,比如一个委托:

namespace  TestSpace  {
      delegate  string  TestDelegate(string  value);
      public  class  TestClass  {
public  TestClass()  {
                  }
                  public  void  GetValue(string  value)  {
                          return  value;
                  }
        }
}

使用示例:


TestClass  obj  =  new  TestClass();
//获取类型,实际上这里也可以直接用typeof来获取类型
Type  t  =  Type.GetType(“TestSpace.TestClass”);
//创建代理,传入类型、创建代理的对象以及方法名称
TestDelegate  method  =  (TestDelegate)Delegate.CreateDelegate(t,obj,”GetValue”);
String  returnValue  =  method(“hello”);

优缺点
优点:

1、反射提高了程序的灵活性和扩展性。

2、降低耦合性,提高自适应能力。

3、它允许程序创建和控制任何类的对象,无需提前硬编码目标类。

缺点:

1、性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用。

2、使用反射会模糊程序内部逻辑;程序员希望在源代码中看到程序的逻辑,反射却绕过了源代码的技术,因而会带来维护的问题,反射代码比相应的直接代码更复杂。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值