65.9K
CodeProject 正在变化。 阅读更多。
Home

应用反射或停止切换

starIconstarIconemptyStarIconemptyStarIconemptyStarIcon

2.00/5 (9投票s)

2004年10月19日

2分钟阅读

viewsIcon

25602

downloadIcon

168

本文演示了使用反射实现开发人员每天面临的常见任务之一的实际应用。

注意

作者的意图并非提供.NET反射的完整概述。本文演示了使用反射实现开发人员每天面临的常见任务之一的实际应用。

什么是 Reflection?

.NET反射是用于解决高级任务的低级API的典型例子。那么它是什么?反射(同义词:内省)是一个为代码提供关于自身信息的子系统。听起来有点复杂,显然,一个例子是掌握这个想法的最佳方式。假设我们有一个类MyCar,它提供了一个Start方法

public class MyCar
{
    public void Start() 
    {
       Console.WriteLine("Started!"); 
    }
}

// Main method

MyCar car = new MyCar();
car.Start();

现在我们将深入研究内省。我们将获取MyCar的一些类型信息

Type myCarType = typeof(MyCar);

myCarType现在拥有一个对描述MyCar类的元数据的引用。我们可以获取有关其属性、字段、方法、事件等等的更多信息。您可以查阅MSDN或Code Project文章关于反射的内容。我们需要知道的是,我们是否可以获取这些信息。

此外,.NET允许我们根据完整的类型名称获取类型信息

Type myCarType = Type.GetType("Serge.ReflectionSample.MyCar", false, true);

在获得此引用后我们可以做什么?当然,创建一个类实例(一个object)。为了做到这一点,您需要获取构造函数信息

// make sure the type was found by the runtime
if(myCarType != null)
{
   // get default constructor
   ConstructorInfo ci = myCarType.GetConstructor(new Type[]{});

   // call constructor returning object reference
   object myCarReflected = ci.Invoke(new object[]{});
}

现在我们有了一个对新创建的MyCar类型对象的引用。接下来做什么?

显然,我们不能对类型为object的引用做太多操作,但是.NET提供的已经足够了。没有什么能阻止我们将myCarReflected转换为MyCar,不是吗?另一种解决方案。假设MyCar实现了IVehicle,并且我们的应用程序不关心接口的实现。所以我们将myCarReflected转换为IVehicle并使用接口成员。

让我们总结一下

  • 我们可以通过名称获取关于任何类型的信息。
  • 我们可以获得对所需构造函数的引用。
  • 我们可以使用此信息实例化一个对象。
  • 我们可以将一个对象转换为支持的类型之一。

我们的应用程序

许多开发人员都面临着使用switch运算符来判断需要实例化哪个类的必要性。作者作为一名高级.NET开发人员,曾看到过超过数页的switch-blocks。在一个项目中,应用程序必须解析一个XML模板文件并生成相应对象的内存树。此外,它还必须提供一种方法,无需修改核心功能即可将新的节点类型导入系统。在本文中,我提出了一种简化的解决方案 - 没有单独的程序集或XML节点。一个精明的读者可能已经猜到了我要表达什么。如果不是,请浏览代码,它已经有足够的文档。如果是,也鼓励您看一看。

结果

如有必要,请随时提问。

© . All rights reserved.