typeof(T)可能返回null

red*_*edb 9 c# clr clr4.0

typeof通过TypeBuilder创建的类型上使用运算符时,运算符将返回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);
    }
Run Code Online (Sandbox Code Playgroud)

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

Eri*_*ert 20

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

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

我很好奇为什么会这样

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

我不得不强调这是一个猜测; 我还没有实际调试过它.

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

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

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

怎么预防呢?

如果在键入"typeof(MyType)"时疼痛,请停止输入.


Mik*_*ron 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
Run Code Online (Sandbox Code Playgroud)

  • @Mike:您的"无例外"声明严格来说并不准确.假设您在编译时创建了一个类型C <T>,然后在运行时创建了一个类型X,然后使用反射创建了一个C <X>的实例.如果C <T>中包含生成typeof(T)的代码,那么生成的代码应该能够返回X的类型对象.但是在*expression*的实际文本中,"typeof(T)",**"T"必须是编译时已知的东西**.这可以是在运行时解析的类型参数,但它必须是*编译器已知的*. (3认同)
  • 让我重新说一下.`typeof` _only_适用于编译时存在的类型.期.没有例外.尝试在代码中加入`typeof(MyType)`,看看会发生什么.编辑:@Eric说的是什么.如果_HE_说是这样,_it的friggin so_. (2认同)