c# 反射的应用

简述

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

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

您可以使用使用反射获取类型,根据类型来动态创建对象,可以获取方法以及动态调用方法,可以动态创建委托。然后,可以调用类型的方法或访问其字段和属性。
扩展:
如何使用反射获取类型
首先我们来看如何获得类型信息。
获得类型信息有两种方法,一种是得到实例对象
这个时侯我仅仅是得到这个实例对象,得到的方式也许是一个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、使用反射会模糊程序内部逻辑;程序员希望在源代码中看到程序的逻辑,反射却绕过了源代码的技术,因而会带来维护的问题,反射代码比相应的直接代码更复杂。

相关推荐

  1. c# 应用

    2024-04-22 10:18:01       37 阅读
  2. C++实现方式

    2024-04-22 10:18:01       29 阅读
  3. 理解

    2024-04-22 10:18:01       52 阅读
  4. 面试宝典:深入剖析golang 在orm模型中应用

    2024-04-22 10:18:01       35 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-22 10:18:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-22 10:18:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-22 10:18:01       82 阅读
  4. Python语言-面向对象

    2024-04-22 10:18:01       91 阅读

热门阅读

  1. elasticsearch 关于向量化检索

    2024-04-22 10:18:01       37 阅读
  2. 4.21算法

    2024-04-22 10:18:01       35 阅读
  3. Leetcode 4.21

    2024-04-22 10:18:01       36 阅读
  4. 算法之前缀和和差分

    2024-04-22 10:18:01       32 阅读
  5. 广州大学2023-2024学年第一学期《计算机网络》A卷

    2024-04-22 10:18:01       37 阅读
  6. SWCTF

    SWCTF

    2024-04-22 10:18:01      37 阅读