关于c#:使用静态构造函数(Jon Skeet Brainteaser)

Using Static Constructor (Jon Skeet Brainteaser)

作为一个相对新手,我尽可能多地阅读某个特定主题,尽可能多地测试/编写代码。我在看乔恩的一个脑筋急转弯(问题2),我的输出与答案不同。这使得我来到这里,询问最近的版本中是否发生了变化,并了解其他人从代码中得到了什么输出。

问题是,"将显示什么,为什么,以及你有多自信?"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using System;

class Foo
{
    static Foo()
    {
        Console.WriteLine ("Foo");
    }
}

class Bar
{
    static int i = Init();

    static int Init()
    {
        Console.WriteLine("Bar");
        return 0;
    }
}

class Test
{
    static void Main()
    {
        Foo f = new Foo();
        Bar b = new Bar();
    }
}

什么,如果有的话,会导致我们得到两个不同的答案?


现在在调试器之外的释放模式下尝试;-p

我使用/不使用调试器得到不同的结果。调试程序会扰乱许多细微的细微差别/优化,所以我只能猜测这是调试程序最重要的时候之一。这使得调试更加困难;-p


Jon自己的答案页面对此进行了讨论。我不是一个C家伙,但看起来系统在何时调用静态foo代码(因此写"foo")上只有一个选择,但是它在本质上有无限的自由来决定何时初始化Bar.i(它将写"bar"),所以它可以在类被加载时,或者在它第一次被使用时,或者根本没有发生。


它在调试模式下打印foo,bar,在释放模式下打印foo。所以现在所发生的是发布代码被优化,优化会导致首先调用BAR——但是不能保证总是这样。


我想FOO栏会被打印出来。静态类型构造函数将首先在foo中执行,然后在bar类上调用init方法。但我不知道这种行为是否会改变。这很有趣。


只要看看它,如果它除了"foobar"之外还显示其他东西,我会很惊讶的。

出于简单的原因,您首先访问foo,因此它的静态构造函数将运行。在实例化条时后跟静态字段初始值设定项。

很高兴被纠正。