另一个答案展示了在运行时获取(可能未加载)Assembly
中定义的Type
的最佳方法:
var T1 = Type.GetType("System.Web.Configuration.IAssemblyCache, " +
"System.Web, " +
"Version=4.0.0.0, " +
"Culture=neutral, " +
"PublicKeyToken=b03f5f7f11d50a3a");
正如您所见,不幸的是该方法要求您提供完整的Type
的AssemblyQualifiedName,并且不适用于我尝试过的任何程序集名称的缩写形式。这在某种程度上破坏了我们的主要目的。如果您已经知道有关程序集的这么多细节,那么自己加载它也不会更难:
var T2 = Assembly.Load("System.Web, " +
"Version=4.0.0.0, " +
"Culture=neutral, " +
"PublicKeyToken=b03f5f7f11d50a3a")
.GetType("System.Web.Configuration.IAssemblyCache");
尽管这两个示例看起来相似,但它们执行非常不同的代码路径;例如,请注意,后一个版本在
Assembly.GetType
上调用了一个
实例重载,而不是
静态调用
Type.GetType
。因此,第二个版本可能更快或更有效。无论哪种方式,似乎都会到达以下CLR内部方法,并将第二个参数设置为
false
,这就是为什么
两种方法都不费力地为您搜索所需程序集的原因。
private static RuntimeType
LoadClrTypeWithPartialBindFallback(
String typeName,
bool partialFallback);
从这些不便中向前迈出的微小一步是改为自己调用此CLR方法,但将
partialFallback
参数设置为
true。在此模式下,该函数将接受
AssemblyQualifiedName
的截断版本,并根据需要
查找和加载相关程序集:
static Func<String, bool, TypeInfo> LoadClrTypeWithPartialBindFallback =
typeof(RemotingServices)
.GetMethod("LoadClrTypeWithPartialBindFallback", (BindingFlags)0x28)
.CreateDelegate(typeof(Func<String, bool, TypeInfo>))
as Func<String, bool, TypeInfo>;
// ...
var T3 = LoadClrTypeWithPartialBindFallback(
"System.Web.Configuration.IAssemblyCache, System.Web",
true); // <-- enables searching for the assembly
这个示例可以正常工作,并且还支持像之前的示例一样指定完整的
AssemblyQualifiedName
。这是一个小改进,但它仍然不是完全未经限定的命名空间搜索,因为你仍然需要指定程序集的短名称,即使它可能可以从类型名称本身中推断出命名空间。