Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# typeof(T)可以返回null_C#_Clr_Clr4.0 - Fatal编程技术网

C# typeof(T)可以返回null

C# typeof(T)可以返回null,c#,clr,clr4.0,C#,Clr,Clr4.0,对通过TypeBuilder创建的类型使用typeof运算符时,该运算符将返回null 我很好奇为什么会发生这种情况,以及如何预防 我开始认为这是即时窗口中的VS错误,但我不太确定。 首先责备别人是很容易的 好的。。。复制问题的代码: static void Main() { AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly( n

对通过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);
    }
如果在VS即时窗口中的变量
o
和类型
typeof(MyType)
后放置断点,则会出现问题

如果在VS即时窗口中的变量“o”和类型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
键入MyMethod(),其中T:class{
返回类型(T);
}
类型myType=//动态创建类型;
类型myOtherType=//调用MyMethod,将myType作为类型参数
Assert(myType==myOtherType)//不会开火
在通过TypeBuilder创建的类型上使用typeof运算符时,该运算符将返回null

首先,这个说法是正确的。如果您编写这个程序,然后在调试器中停止它,并在即时窗口中说“typeof(MyType)”,返回的结果是“null”

我很好奇为什么会这样

把我打得要死。如果我不得不猜测的话,我会说可能表达式计算器正在与CLR的调试子系统通信,以尝试通过其名称获取类型的元数据标记,而CLR正在返回一些垃圾零标记,而不是生成错误

我急忙强调,这是一种猜测;我实际上还没有调试它

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

这似乎是可能的。它应该做的正确的事情是给出错误“类型或命名空间'MyType'在此范围内无效”。这个bug几乎肯定会出现在C#runtime expression evaluator中,而不是立即窗口本身

谢谢你提醒我注意这个问题。我将向expression evaluator维护人员提交一个bug,看看他们是否能够解决这个问题

如何预防


如果你输入“typeof(MyType)”时感觉不舒服,那就停止输入。

你能发布一个简短但完整的程序来演示这个问题吗?是的,我们不能在没有看到一些代码的情况下真正确定问题。你怎么能对编译时不存在的类型使用
typeof
?真的需要在这里看到一些代码…@Jon在将CLR更正为编译器之前,我实际上输入了错误的CLR:P尽管如此,您仍然是正确的,因为我们需要看到codez@Marc当前位置问题是,你和里卡多正在谈论彼此的过去;他说的是运行时表达式计算器中typeof运算符的行为,而您说的是编译代码中typeof的行为。这是两个完全不同的子系统,它们使用CLR的不同部分。里卡多显然在运行时表达式计算器中发现了一个奇怪之处;在编译器版本的操作符中肯定找不到类似的奇怪之处,它只执行静态分析。。。为什么我需要符号?我只需要元数据。如果执行o.GetType(),它将工作,但typeof(MyType)不会。我不认为符号在这种情况下起作用。如果这是真的,那么就不可能在任何缺少符号的程序集中使用typeof,事实并非如此。
typeof
是一个编译器构造,而不是.NET构造。它解析恰好是名称的编译时字符束,并将它们转换为它们所表示的
System.Type
System.Object.GetType()
是一个运行时概念,它直接返回
类型
,而无需复杂的编译器工作。@Ricardo:Mike是对的。“typeof”的意思是“嘿,编译器,这是一个字符串,它是您知道的类型的名称。它是什么类型?”您的类型是在运行时创建的;编译器对此一无所知。如果要为动态创建的类型获取类型对象,请向类型生成器索取;这就是为什么它被称为类型生成器。让我重新措辞
typeof
仅适用于编译时存在的类型。时期没有例外。尝试在代码中放入
typeof(MyType)
,看看会发生什么。编辑:埃里克说了什么。如果他说是这样,那就太糟糕了。@Mike:你的“无例外”陈述严格来说并不准确。假设您在编译时创建了一个类型C,然后在运行时创建了一个类型X,然后使用反射创建了一个C实例。如果C中有生成typeof(T)的代码,那么生成的代码应该能够返回X的type对象。但是在表达式的实际文本中,“typeof(T)”,则“T”必须是编译时已知的内容。这可以是在运行时解析的类型参数,但它必须是编译器已知的。我遇到过类似的行为,在一个泛型
Foo()
方法中,用
typeof(T)
馈送的VS.NET immediate window返回
null
。埃里克:你想获得源代码吗?@PierreArnaud:我从2012年起就没有在微软工作过。如果这个问题给您带来困难,我建议您与VisualStudio团队中的某个人联系。祝你好运