This article is currently in the process of being translated into Chinese (~93% done).
Instantiating a class
到目前为止,我们已经使用的是已经实例化后的 .NET 类型或对象。但是在反射的加持下,我们实际上可以在运行时来进行实例化操作,只需要知道我们所希望实例化类的名称。这里有多种方法可以实现,但是我更喜欢获取我希望用的构造函数的引用,通过调用它将其返回值作为我的实例。下面就是这样的一个例子,首先是代码,之后我将对其进行解释。
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
namespace ReflectionTest
{
class Program
{
static void Main(string[] args)
{
Type testType = typeof(TestClass);
ConstructorInfo ctor = testType.GetConstructor(System.Type.EmptyTypes);
if(ctor != null)
{
object instance = ctor.Invoke(null);
MethodInfo methodInfo = testType.GetMethod("TestMethod");
Console.WriteLine(methodInfo.Invoke(instance, new object[] { 10 }));
}
Console.ReadKey();
}
}
public class TestClass
{
private int testValue = 42;
public int TestMethod(int numberToAdd)
{
return this.testValue + numberToAdd;
}
}
}
为了测试这个功能,我事先定义了一个简单的类 TestClass。它仅仅包含一个私有字段和一个公共方法。该方法将私有字段的值与参数的值相加,并将其返回出来。现在我们想要的是创建 TestClass 类的对象,并调用其 TestMethod 方法,将该方法的结果输出到控制台中。
在该方法中,我们可以直接在 TestClass 上使用 typeof(),但在某些时候,你可能只需要通过所需类的名称来实现这个功能。在这样的情况下,你可以通过声明它的程序集来获得对它的引用,如关于 Type 的章节内所示。
因此,通过对某个类的 Type 类型引用,我们可以使用 GetConstructor() 方法来请求默认构造函数,在该方法中需要传递一个 System.Type.EmptyTypes 对象作为其参数。如果我们想获取指定的构造函数,我们需要提供一个 Type 对象数组,其中每一个 Type 对象都定义了我们需要查找的构造函数所需的参数。
一旦我们获得了构造函数的引用,我们只需要简单地调用 Invoke() 函数就可以创建一个 TestClass 类的新实例。我们向 Invoke() 方法内将 null 作为参数传入,因为我们不需要指定任何参数。我们使用 GetMethod() 方法,通过我们想要调用的方法名称来获取 TestMethod() 方法,之后我们再次使用 Invoke() 这个神奇的方法来调用这个函数。这次我们需要通过对象数组来指定参数。我们立即调用这个方法,并将数字 10 作为我们需要的参数,并将方法执行的结果输出。可以看到,这一切都是通过反射所得到的,很神奇吧。