C# 反射
在很多开发场景中,可以在开发过程中访问应用程序所需的所有程序集和代码。然而,有些应用程序要求可扩展,则只能通过编写代码,动态的添加外部程序集中包含的功能才能完成。根据需求,可能还需要动态的生成程序集。我将在下面介绍反射的原理和用法。
1.反射概述
很多时候,可以在开发过程中直接访问类型。然而,有些时候却需要在运行是动态的加载程序集,以及其中包含的类型和方法。例如支持插件的应用程序编写为可以动态运行的插件,机试在应用程序开发的时候插件还不存在。
反射可以在运行时加载程序集,动态创建类型的实例,并将类型绑定到现有对象。然后就能够调用该类型的方法并访问其属性了。
2.如何加载程序集
在运行时加载程序集后就可以检查其特性,并且根据加载时使用的方法创建类型的实例并运行方法。下面列出了可以用来加载程序集的方法:
Assembly.Load 按照名称加载程序集,通常是从全局程序集缓存中加载。
Assembly.LoadFile 按照指定的文件名加载程序集。
Assembly.LoadFrom 通过给定的路径或者文件名加载程序集。
Assembly.ReflectionOnlyLoad 尽在反射上下文中加载程序集,通常是从GAC中加载。
Assembly.ReflectionOnlyLoadFrom 展昭指定的文件名,尽在反射上下文中加载程序集。
在近反射上下文中加载程序集只允许检查程序集,但不能创建类型的示例或运行方法。因此,只能用于需要检查程序集其中的代码时。通常,开发人员使用仅反射上下文来检查为其他平台或者其他.NET 版本编译的程序集。
3.如何创建实例和调用方法
通过创建Type类型的实例,可以使用反射创建在运行时之前不可用的类型的实例。尽管可以简单的指定现有类型,但是典型的做法是,通过调用Assembly.GetType并指定在程序集中加载的类型名字来创建Type。
一旦创建了Type实例就可以访问该类型的成员了。调用Type.GetMethod可以创建MethodInfo的实例。GetMethod要求指定方法的名字(字符串)和方法所需的参数(Type数组)。
Type t=typeof (StringBuilder); ConstructorInfo ci =t.GetCinstructon(new Type[] {typeof String}); Object sb=ci.Invoke(new Object[]{"Hello,"}); MethodInfo sbAppend =t.GetMethod("Appand",new Type[]{typeof(String)}); Object result =sbAppend.Invoke(sb,new Object []{"World!"}); Console.WriteLine(result);