我在我的(巨大的).NET 4 项目中遇到了一个奇怪的行为。在代码中的某个位置,我指的是完全限定类型,例如:
System.Type type = typeof (Foo.Bar.Xyz);
稍后,我这样做:
System.Type type = System.Type.GetType ("Foo.Bar.Xyz");
我回来了
null
.我无法理解为什么会发生这种情况,因为我的类型名称是正确的,并且我已经检查了其他类型并且它们得到了正确解决。此外,以下 LINQ 查询查找类型:var types = from assembly in System.AppDomain.CurrentDomain.GetAssemblies ()
from assemblyType in assembly.GetTypes ()
where assemblyType.FullName == typeName
select assemblyType;
System.Type type = types.FirstOrDefault ();
有什么原因
System.Type.GetType
会失败吗?我终于不得不求助于这段代码而不是
GetType
:System.Type MyGetType(string typeName)
{
System.Type type = System.Type.GetType (typeName);
if (type == null)
{
var types = from assembly in System.AppDomain.CurrentDomain.GetAssemblies ()
from assemblyType in assembly.GetTypes ()
where assemblyType.FullName == typeName
select assemblyType;
type = types.FirstOrDefault ();
}
return type;
}
最佳答案
如果你只是给出一个类名(当然,它确实需要在命名空间方面是完全限定的)Type.GetType(string)
只会查看当前正在执行的程序集和 mscorlib。如果要从任何其他程序集中获取类型,则需要指定包含程序集信息的绝对全名。正如弗朗索瓦所说, Type.AssemblyQualifiedName
是看到这一点的好方法。这是一个例子:
using System;
using System.Windows.Forms;
class Test
{
static void Main()
{
string name = typeof(Form).AssemblyQualifiedName;
Console.WriteLine(name);
Type type = Type.GetType(name);
Console.WriteLine(type);
}
}
输出:
System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
System.Windows.Forms.Form
请注意,如果您使用的是强命名程序集(如
Form
在这种情况下),则必须包含所有程序集信息 - 版本控制、公钥 token 等。如果您使用的是非强命名程序集,则更容易 - 例如:
Foo.Bar.Baz, MyCompany.MyAssembly
对于名为
Baz
的类型在命名空间 Foo.Bar
, 在组装 MyCompany.MyAssembly
.请注意末尾没有“.dll” - 这是文件名的一部分,但不是程序集名称。您还应该注意嵌套类和泛型等 C# 名称和 CLR 名称之间的区别。例如,
typeof(List<>.Enumerator)
名称为 System.Collections.Generic.List`1+Enumerator[T]
.泛型方面很难解决,但嵌套类型位很容易——它只是用“+”而不是“.”来表示。你会在 C# 中使用。
关于assemblies - 如果 typeof(Xyz) 存在,为什么 System.Type.GetType ("Xyz") 返回 null?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3758209/