开发者

Using Static Constructor (Jon Skeet Brainteaser)

As a relative newbie I try to read as much as I can about a particular subject and test/write as much code as I can. I was looking at one of Jons Brainteasers (question #2) and my output was different than the answer. Which makes brings me here to ask if something has changed in recent versions and to see what output others are getting from this code.

The question i开发者_运维知识库s, "What will be displayed, why, and how confident are you?"

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

What, if anything, would cause us to get two different answers?


Now try it in release mode, outside of the debugger ;-p

I get different results with/without a debugger. The debugger upsets a lot of subtle nuances / optimisations, so I can only guess this is one of those times where the debugger matters. Which makes it even harder to debug ;-p


Jon's own answers page discusses this. I'm not a C# guy, but it seems like the system has exactly one choice of when to call the static foo code (and therefore write "Foo") but it has essentially infinite freedom to decide when to initialize Bar.i (which will write "Bar"), so it can happen either when the class is loaded, or when it is first used, or not at all.


It prints Foo, Bar in Debug mode and Bar, Foo in Release mode. So what is happening is the Release code is optimized and the optimization causes Bar to be called first - but there is no guarantee that will always be the case.


Just looking at it, I'd be surprised if it displayed anything else but "FooBar".

For the simple reason you are accessing Foo first, so its static constructor will run. Followed by the static field initializer when instantiating Bar.

Happy to be corrected.


I think that foo bar will be printed. The static type constructor would be executed first in Foo, then the Init method would be called on the Bar class. I don't know about whether or not the behavior could change though. This is interesting.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜