使用静态构造函数(Jon Skeet Brainteaser)

作为一个相对新手,我尽可能多地阅读关于特定主题的内容,并尽可能多地测试/编写代码。 我正在看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(); } } 

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

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

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

Jon自己的答案页面对此进行了讨论。 我不是C#家伙,但似乎系统只有一个选择何时调用静态foo代码(因此写“Foo”),但它基本上有无限的自由来决定何时初始化Bar.i (其中将写“Bar”),因此它可以在加载类时,或者首次使用时发生,或者根本不发生。

它在调试模式下打印Foo,Bar,在释放模式下打印Bar,Foo。 所以发生的事情是发布代码已经过优化,优化会导致首先调用Bar – 但不能保证始终如此。

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

出于简单的原因,您首先访问Foo,因此它的静态构造函数将运行。 在实例化Bar时跟随静态字段初始化程序。

很高兴得到纠正。

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