19

作为一个相对新手,我尝试尽可能多地阅读特定主题并尽可能多地测试/编写代码。我正在查看Jons Brainteasers之一(问题 #2),我的输出与答案不同。这让我来这里询问最近的版本是否发生了变化,并查看其他人从这段代码中得到了什么输出。

问题是,“将展示什么,为什么,以及你有多自信?”

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();
    }
}

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

4

5 回答 5

25

现在在调试器之外以发布模式尝试它;-p

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

于 2009-10-29T17:22:38.633 回答
6

乔恩自己的答案页面讨论了这一点。我不是 C# 人,但似乎系统只有一个选择何时调用静态foo代码(因此写“Foo”),但它本质上具有无限的自由来决定何时初始化Bar.i(这将写为“Bar "),因此它可以在加载类时发生,或者在第一次使用时发生,或者根本不发生。

于 2009-10-29T17:21:44.333 回答
4

它在 Debug 模式下打印 Foo, Bar,在 Release 模式下打印 Bar, Foo。所以发生的事情是发布代码被优化并且优化导致 Bar 首先被调用 - 但不能保证总是如此。

于 2009-10-29T17:24:06.007 回答
0

只是看着它,如果它显示除“FooBar”之外的任何其他内容,我会感到惊讶。

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

很高兴得到纠正。

于 2009-10-29T17:21:49.693 回答
0

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

于 2009-10-29T17:28:40.483 回答