可能是Visual Studio 2015中的C#编译器错误

彼得·佩罗

我认为这是一个编译器错误。

当使用VS 2015进行编译时,以下控制台应用程序可以正常编译和执行:

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var x = MyStruct.Empty;
        }

        public struct MyStruct
        {
            public static readonly MyStruct Empty = new MyStruct();
        }
    }
}

但是现在变得很奇怪:该代码可以编译,但是TypeLoadException在执行时会抛出a

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var x = MyStruct.Empty;
        }

        public struct MyStruct
        {
            public static readonly MyStruct? Empty = null;
        }
    }
}

您是否遇到相同的问题?如果是这样,我将向Microsoft提出问题。

该代码看起来毫无意义,但我使用它来提高可读性并消除歧义。

我有不同的重载的方法,如

void DoSomething(MyStruct? arg1, string arg2)

void DoSomething(string arg1, string arg2)

以这种方式调用方法...

myInstance.DoSomething(null, "Hello world!")

...无法编译。

呼唤

myInstance.DoSomething(default(MyStruct?), "Hello world!")

或者

myInstance.DoSomething((MyStruct?)null, "Hello world!")

可以,但是看起来很丑。我更喜欢这样:

myInstance.DoSomething(MyStruct.Empty, "Hello world!")

如果我将Empty变量放入另一个类,则一切正常:

public static class MyUtility
{
    public static readonly MyStruct? Empty = null;
}

奇怪的行为,不是吗?


更新2016-03-29

我在这里打开了一张票:http : //github.com/dotnet/roslyn/issues/10126


更新2016-04-06

新票已在此处打开:https : //github.com/dotnet/coreclr/issues/4049

科里

这不是2015年的错误,但可能是C#语言错误。下面的讨论涉及为什么实例成员不能引入循环,以及为什么aNullable<T>会导致此错误,但不适用于静态成员。

我将其提交为语言错误,而不是编译器错误。


在VS2013中编译此代码会产生以下编译错误:

类型为“ System.Nullable”的结构成员“ ConsoleApplication1.Program.MyStruct.Empty”导致结构布局中的循环

快速搜索即可找到以下答案

具有包含自身作为成员的结构是不合法的。

不幸的System.Nullable<T>是,用于值类型的可为空的实例的类型也是一个值类型,因此必须具有固定的大小。将其MyStruct?视为引用类型是很诱人的,但实际上并非如此。的大小MyStruct?基于...的大小,MyStruct这显然在编译器中引入了循环。

举个例子:

public struct Struct1
{
    public int a;
    public int b;
    public int c;
}

public struct Struct2
{
    public Struct1? s;
}

使用,System.Runtime.InteropServices.Marshal.SizeOf()您会发现它的Struct2长度为16个字节,这表明它Struct1?不是引用,而是比更长4个字节(标准填充大小)的结构Struct1


什么是发生在这里

为了响应朱利叶斯·德普拉(Julius Depulla)的回答和评论,这是您访问字段实际发生的情况static Nullable<T>从此代码:

public struct foo
{
    public static int? Empty = null;
}

public void Main()
{
    Console.WriteLine(foo.Empty == null);
}

这是从LINQPad生成的IL:

IL_0000:  ldsflda     UserQuery+foo.Empty
IL_0005:  call        System.Nullable<System.Int32>.get_HasValue
IL_000A:  ldc.i4.0    
IL_000B:  ceq         
IL_000D:  call        System.Console.WriteLine
IL_0012:  ret         

第一条指令获取静态字段的地址,foo.Empty并将其压入堆栈。保证该地址是非空的,就像Nullable<Int32>结构一样,不是引用类型。

接下来,调用Nullable<Int32>隐藏成员函数get_HasValue以检索HasValue属性值。如前所述,这不能导致空引用,因为值类型字段的地址必须为非空值,而与该地址中包含的值无关。

剩下的只是将结果与0进行比较,然后将结果发送到控制台。

在此过程中,无论如何都不可能“在类型上调用null”。值类型没有空地址,因此对值类型的方法调用不能直接导致空对象引用错误。这就是为什么我们不称它们为引用类型的原因。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Visual Studio 可能是错误的编译器错误

来自分类Dev

Visual Studio 2015更新1中C ++的内部编译器错误

来自分类Dev

如何在Visual Studio 2015中使用roslyn C#编译器?

来自分类Dev

可能的Visual Studio 2015 C ++编译器和IntelliSense错误

来自分类Dev

Visual Studio 2015 的 r 工具中的 Rcpp 编译器错误

来自分类Dev

如何停止C#编译器输出在Visual Studio 2015输出窗口中换行?

来自分类Dev

Visual Studio 2015中的编译器是什么

来自分类Dev

有时Visual Studio IDE0032建议可能是错误的做法吗?

来自分类Dev

这是Visual Studio 2010编译器中的错误吗?

来自分类Dev

仅在发行版中的Visual Studio 2019“ C1001内部编译器错误”

来自分类Dev

使用Intel C ++编译器的Visual Studio中的OpenMP

来自分类Dev

我无法在Visual Studio Code中启动“ javascript”调试器(可能是因为已安装HPC)

来自分类Dev

Visual Studio 2015-缺少64位编译器

来自分类Dev

Visual Studio 2015-编译器警告(等级2)C4146

来自分类Dev

C# 代码在 Visual Studio 2019 中有效,但在在线编译器中无效

来自分类Dev

使用g ++编译器在Visual Studio中编译C ++程序会在最后生成%

来自分类Dev

哪些编译器选项用于在Visual Studio中编译C ++ STL类/函数?

来自分类Dev

在Visual Studio 2013中更改编译器错误语言

来自分类Dev

在Visual Studio 2013中更改编译器错误语言

来自分类Dev

static_assert(std :: is_abstract)在Visual Studio 2013中导致编译器错误

来自分类Dev

是否应该在Visual Studio C#编译器中将此列表初始化器行为报告为错误?

来自分类Dev

什么是 ?和@符号表明此编译器错误?-Visual Studio 2013编译器

来自分类Dev

什么是 ?和@符号表明此编译器错误?-Visual Studio 2013编译器

来自分类Dev

从 Visual Studio 代码中排除 C# 编译器警告

来自分类Dev

如何在ANSI C中使用Visual Studio 2015编程(作为编辑器和编译器)?

来自分类Dev

至少在以下一种编辑器中,降价语法的标题可能是彩色的:Sublime Text 3,Vim或Visual Studio Code?

来自分类Dev

是否可以将Visual C ++ v120编译器工具集添加到Visual Studio 2015?

来自分类Dev

Visual Studio可能的缓存错误C#

来自分类Dev

在Visual Studio 2013中使用Roslyn编译器

Related 相关文章

  1. 1

    Visual Studio 可能是错误的编译器错误

  2. 2

    Visual Studio 2015更新1中C ++的内部编译器错误

  3. 3

    如何在Visual Studio 2015中使用roslyn C#编译器?

  4. 4

    可能的Visual Studio 2015 C ++编译器和IntelliSense错误

  5. 5

    Visual Studio 2015 的 r 工具中的 Rcpp 编译器错误

  6. 6

    如何停止C#编译器输出在Visual Studio 2015输出窗口中换行?

  7. 7

    Visual Studio 2015中的编译器是什么

  8. 8

    有时Visual Studio IDE0032建议可能是错误的做法吗?

  9. 9

    这是Visual Studio 2010编译器中的错误吗?

  10. 10

    仅在发行版中的Visual Studio 2019“ C1001内部编译器错误”

  11. 11

    使用Intel C ++编译器的Visual Studio中的OpenMP

  12. 12

    我无法在Visual Studio Code中启动“ javascript”调试器(可能是因为已安装HPC)

  13. 13

    Visual Studio 2015-缺少64位编译器

  14. 14

    Visual Studio 2015-编译器警告(等级2)C4146

  15. 15

    C# 代码在 Visual Studio 2019 中有效,但在在线编译器中无效

  16. 16

    使用g ++编译器在Visual Studio中编译C ++程序会在最后生成%

  17. 17

    哪些编译器选项用于在Visual Studio中编译C ++ STL类/函数?

  18. 18

    在Visual Studio 2013中更改编译器错误语言

  19. 19

    在Visual Studio 2013中更改编译器错误语言

  20. 20

    static_assert(std :: is_abstract)在Visual Studio 2013中导致编译器错误

  21. 21

    是否应该在Visual Studio C#编译器中将此列表初始化器行为报告为错误?

  22. 22

    什么是 ?和@符号表明此编译器错误?-Visual Studio 2013编译器

  23. 23

    什么是 ?和@符号表明此编译器错误?-Visual Studio 2013编译器

  24. 24

    从 Visual Studio 代码中排除 C# 编译器警告

  25. 25

    如何在ANSI C中使用Visual Studio 2015编程(作为编辑器和编译器)?

  26. 26

    至少在以下一种编辑器中,降价语法的标题可能是彩色的:Sublime Text 3,Vim或Visual Studio Code?

  27. 27

    是否可以将Visual C ++ v120编译器工具集添加到Visual Studio 2015?

  28. 28

    Visual Studio可能的缓存错误C#

  29. 29

    在Visual Studio 2013中使用Roslyn编译器

热门标签

归档