如果typeof(Xyz)存在,为什么System.Type.GetType("Xyz")返回null? [英] Why would System.Type.GetType("Xyz") return null if typeof(Xyz) exists?

查看:154
本文介绍了如果typeof(Xyz)存在,为什么System.Type.GetType("Xyz")返回null?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在(巨大的).NET 4项目中遇到了一个奇怪的行为.在代码的某个时刻,我指的是完全限定的类型,例如:

I have come across a strange behaviour in my (huge) .NET 4 project. At some point in the code, I am referring to a fully qualified type, say:

System.Type type = typeof (Foo.Bar.Xyz);

后来,我这样做:

System.Type type = System.Type.GetType ("Foo.Bar.Xyz");

,然后我又回到null.我无法理解为什么会这样,因为我的类型名称正确,并且我已经检查了其他类型,并且可以正确解析它们.此外,以下LINQ查询会找到类型:

and I get back null. I cannot make sense of why this is happening, because my type name is correct, and I have checked with other types and they get resolved properly. Moreover, the following LINQ query finds the type:

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:

I have finally had to resort to this piece of code instead of 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.如果要从任何其他程序集获取类型,则需要指定绝对全名,包括程序集信息.正如François所说, Type.AssemblyQualifiedName 是一个好方法看到这个.这是一个示例:

If you just give a class name (which does need to be fully-qualified in terms of the namespace, of course) Type.GetType(string) will only look in the currently executing assembly and mscorlib. If you want to get types from any other assembly, you need to specify the absolutely full name including the assembly information. As François says, Type.AssemblyQualifiedName is a good way of seeing this. Here's an example:

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

System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
System.Windows.Forms.Form

请注意,如果您使用的是强命名程序集(在本例中为Form),则必须包括程序集信息 all -版本控制,公钥令牌等.

Note that if you're using a strongly named assembly (like Form in this case) you must include all the assembly information - versioning, public key token etc.

如果您使用的名称不是很强的程序集,它会更容易-类似于:

If you're using a non-strongly-named assembly, it's easier - something like:

Foo.Bar.Baz, MyCompany.MyAssembly

表示程序集MyCompany.MyAssembly中命名空间Foo.Bar中名为Baz的类型.请注意,结尾没有".dll",这是文件名的一部分,而不是程序集名称.

for a type called Baz in namespace Foo.Bar, in assembly MyCompany.MyAssembly. Note the absence of ".dll" at the end - that's part of the filename, but not the assembly name.

对于诸如嵌套类和泛型之类的东西,您还应该了解C#名称和CLR名称之间的区别.例如,typeof(List<>.Enumerator)的名称为System.Collections.Generic.List`1+Enumerator[T].泛型方面很难解决,但是嵌套类型位很容易-只需用"+"代替"即可.您将在C#中使用.

You should also be aware of the differences between C# names and CLR names for things like nested classes and generics. For example, typeof(List<>.Enumerator) has a name of System.Collections.Generic.List`1+Enumerator[T]. The generics side is tricky to work out, but the nested type bit is easy - it's just represented with a "+" instead of the "." you'd use in C#.

这篇关于如果typeof(Xyz)存在,为什么System.Type.GetType("Xyz")返回null?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆