什么时候`Assembly.GetType(name)`返回`null`?

时间:2011-11-15 18:25:58

标签: c# .net reflection .net-assembly

我有一个如下所示的代码

public static Type ToType(Type sType)
{    
    Assembly assembly = Assembly.Load(SerializableType.AssemblyName);
    type = assembly.GetType(sType.Name);
}

更新

在UI中,如果我为基类设置值没有问题,因为它们的程序集创建正常方式,但如果为用户定义的类设置值,则它们的程序集创建不同的方式,如下所示

6 个答案:

答案 0 :(得分:6)

如果找不到类名,则返回null,这很可能是因为类型的Name属性只返回类型名称,而不是命名空间名称来限定它。确保您的Name属性包含符合条件的命名空间。

根据Assembly.GetType(字符串名称)上的MSDN,它返回:

  

表示指定类的对象,如果是类,则为Nothing   找不到。

因此,当你得到null时,它找不到类型名称,最可能的原因是它拼写错误,或者你没有在命名空间前加上类型名称。

  

此方法仅搜索当前程序集实例。名字   参数包括命名空间,但不包括程序集。

或者,类型名称的情况也可能是错误的,有GetType()的版本支持不区分大小写的名称比较的bool参数。

P.S。需要命名空间,因为程序集名称可能不是命名空间的指示符。也就是说,如果我在程序集MySystem.MyClasses.DLL中有一个类型,这并不意味着该类型必须位于MySystem.MyClasses名称空间中。

完整的MSDN页面(总是很好看看抛出/返回的东西)在这里:Assembly.GetType Method(String)

显然程序集存在(或者它将返回null并且你得到NullReferenceException),所以另一种可能性是你没有你期望的相同版本的程序集(即使用此代码的程序具有不同版本的程序集,然后生成数据的代码。

答案 1 :(得分:0)

您的类型可能不公开,默认情况下,反射仅适用于公共类型和成员,除非您提高安全级别,否则类型将为null。

答案 2 :(得分:0)

我努力在我试图使用的dll中找到类型的正确限定名称,但发现GetTypes()在列出所有可用内容时非常有用。在VB中:

    Dim t As Type() = assem.GetTypes()
    Dim s As String = ""
    For i As Integer = 0 To t.Length - 1
        s = s & t(i).FullName & vbCrLf
    Next i
    MsgBox(s)

答案 3 :(得分:0)

以下是UWP应用程序的实际示例。 应用程序命名空间是My_App。类FooPage位于文件夹视图下。获取类型的方法如下:

Type typePage = Assembly.GetExecutingAssembly().GetType("My_App.Views.FooPage}");

如果您不确定类型的名称,请使用以下代码转储所有类并找到感兴趣的类:

foreach(Type t in Assembly.GetExecutingAssembly().GetTypes())
{
    Debug.WriteLine($"{t.Namespace}.{t.Name}");
}

答案 4 :(得分:0)

这不起作用只是因为您从其他程序集加载代码而不是基类程序集。尝试从包含搜索类型定义的其他程序集调用此代码将导致类型解析为null。

这是合理的,因为您必须提供程序集限定类型名称,即Type.AssemblyQualifiedName,而不仅仅是键入全名

如果你定义的派生类在另一个程序集中而不是带有代码示例的基类,那么定义基类的程序集中的代码将不起作用。

这将有效

public static Type ToType(Type type, ITypeResolver typeResolver)
{    
    Assembly assembly = Assembly.Load(SerializableType.AssemblyName);
    type = typeResolver.GetType(assembly, sType.AssemblyQualifiedName);
}

您可以使用类似的TypeResolver(C#7.2)

public interface ITypeResolver
{
    string GetName(Type type);
    Type GetType(Assembly assembly, string typeName);
}

class TypeResolver : ITypeResolver
{
    public string GetName(Type type) => type.AssemblyQualifiedName;
    public Type GetType(Assembly assembly, string typeName) =>
        assembly.GetType(typeName) ?? Type.GetType(typeName);
}

MSDN:

https://docs.microsoft.com/ru-ru/dotnet/api/system.type.gettype?view=netcore-2.1#System_Type_GetType_System_String_

答案 5 :(得分:-1)

我猜你忘记提到命名空间了。正确的方法是

assembly.GetType(MyNameSpace+sType.Name)