typeof(T)可能返回null

时间:2011-06-27 18:58:55

标签: c# clr clr4.0

在通过TypeBuilder创建的类型上使用typeof运算符时,运算符将返回null。

我很好奇为什么会这样,以及如何防止它。


我开始认为这是即时窗口中的VS错误,但我不太确定。 首先责怪他人很容易。

好的......重现问题的代码:

    static void Main()
    {
        AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(
            new AssemblyName("MyAssembly"),
            AssemblyBuilderAccess.RunAndSave);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MyModule");
        TypeBuilder typeBuilder = moduleBuilder.DefineType("MyType", TypeAttributes.Public, typeof(ArrayList));

        ArrayList o = (ArrayList)Activator.CreateInstance(typeBuilder.CreateType());

        Console.WriteLine(o.GetType().Name);
    }

如果在变量o之后放置断点并在VS立即Windows中键入typeof(MyType),则会出现问题。

2 个答案:

答案 0 :(得分:19)

  

在通过TypeBuilder创建的类型上使用typeof运算符时,运算符将返回null。

首先,声明是正确的。如果您编写此程序然后在调试器中将其停止并在即时窗口中说“typeof(MyType)”,则返回的结果为“null”。

  

我很好奇为什么会发生这种情况

击败了我。如果我不得不猜测,我会说表达式评估器可能正在与CLR的调试子系统通信,试图通过其名称获取该类型的元数据标记,并且CLR返回一些垃圾nil标记而不是产生错误。

我必须强调这是一个猜测;我实际上没有调试它。

  

我开始认为这是即时窗口中的VS错误

这似乎很可能。它应该做的正确的事情是给出错误“类型或名称空间'MyType'在此范围内无效”。该错误几乎肯定会在C#运行时表达式求值程序中,而不是在直接窗口本身。

感谢您将此问题提请我注意。我将向表达式评估者维护者提交一个错误,我们将看看他们是否可以解决这个问题。

  

如何预防呢?

如果在输入“typeof(MyType)”时疼痛,请停止输入。

答案 1 :(得分:5)

  

如果在变量“o”之后放置断点并在VS Immediate Windows中键入typeof(MyType),则会出现问题。

嗯,是的。 MyType没有符号(您使用反射定义它!),因此您无法在其上使用typeof

编辑:为了澄清,有一次您可以使用typeof并获得运行时创建的类型:当您使用泛型时。

Type MyMethod<T>() where T : class {
    return typeof(T);
}

Type myType = //create type dynamically;

Type myOtherType = //invoke MyMethod with myType as the type parameter

Debug.Assert(myType == myOtherType); //will not fire