When is a static constructor called in C#?
Asked Answered
K

5

104

When I have class containing a static constructor, is that constructor called when the assembly containing the class is first loaded or when the first reference to that class is hit?

Kinsley answered 17/9, 2009 at 7:58 Comment(1)
It seems this is not a simple question, see: github.com/dotnet/docs/issues/33704Trow
A
108

When the class is accessed for the first time.

Static Constructors (C# Programming Guide)

A static constructor is used to initialize any static data, or to perform a particular action that needs performed once only. It is called automatically before the first instance is created or any static members are referenced.

Arenaceous answered 17/9, 2009 at 8:0 Comment(4)
Interesting that it says "before the first instance is created or any static members are referenced". There's some leeway there in when it actually gets invoked.Spew
@TimBarrass due to some other requirements of specification turns out that "before" is actually "immediately before" - see Jon Skeet's article referenced in other answer - https://mcmap.net/q/209207/-when-is-a-static-constructor-called-in-cEnow
A static constructor is used to initialize any static data NO. Better to use static initializer to initialize static stuff.Zingale
@AlexeiLevenkov not according to the C# PM: github.com/dotnet/docs/issues/33704. Apparently, it is not guaranteed to happen immediately before (even if it is the current behavior) - for this guarantee, module initializers should be used instead.Trow
A
44

It's not quite as simple as you might expect despite straightforward documentation. Jon Skeet's article http://csharpindepth.com/Articles/General/Beforefieldinit.aspx goes into this question in details.

Summary:

Static constructor is guaranteed to be executed immediately before the first reference to a member of that class - either creation of instance or own static method/property of class.

Note that static initilaizers (if there is no static constructor) guaranteed to be executed any time before first reference to particular field.

Assassin answered 17/9, 2009 at 8:2 Comment(3)
Following question #32526128 demonstrate case when "immediate" behavior is quite obvious.Enow
I actually just had the case where a static constructor was called right before the Main method of a console application even began executing!Fancied
@AlexeiLevenkov duplicating my comment above - according to the C# PM: github.com/dotnet/docs/issues/33704, static ctors are not guaranteed to be called immediately before said triggers (even if it is the current behavior) - for this guarantee, module initializers should be used instead.Trow
E
21

The static constructor is called before you use anything in the class, but exactly when that happens is up to the implementation.

It's guaranteed to be called before the first static member is accessed and before the first instance is created. If the class is never used, the static constructor is not guaranteed to be called at all.

Exclosure answered 17/9, 2009 at 8:23 Comment(4)
When it happens is not "up to the implementation" if that implementation follows the ECMA C# spec: "The execution of a static constructor is triggered by the first of the following events to occur within an application domain: [1] An instance of the class is created. [2] Any of the static members of the class are referenced." (Section 17.11, ecma-international.org/publications/standards/Ecma-334.htm)Quinn
@Luke: "The exact timing of static constructor execution is implementation-dependent" ondotnet.com/pub/a/dotnet/2003/07/07/staticxtor.htmlExclosure
@Guffa: That might be the article author's interpretation, but you won't find that wording in the Microsoft or ECMA/ISO versions of the C# spec.Quinn
@Quinn the official C# team position, as far as I can tell, is with Guffa: github.com/dotnet/docs/issues/33704Trow
B
3

In case static method is called from parent class, static constructor will not be called, althogh it is explicitly specified. Here is an example b constructor is not called if b.methoda() is called.

static void Main(string[] args)
{
    b.methoda();
}

class a
{
    public static void methoda()
    {
        //using initialized method data
    }
}

class b : a
{
    static b()
    {
        //some initialization
    }
}    
Burck answered 26/2, 2016 at 12:58 Comment(0)
P
2

There seems to be a gotcha with static constructors that is answered elsewhere but took a while to digest into a simple explanation. All the docs and explanations claim the static constructor/intializers are "guaranteed" to run before the first class is instantiated or the first static field is referenced. The gotcha comes in when you try to put a static singleton in the class that creates an instance of itself (chicken/egg). In this case the static constructor ends up being called after the instance constructor - and in my case the instance constructor contained code that relied on some static data.

Static constructor called after instance constructor?

Static constructor can run after the non-static constructor. Is this a compiler bug?

(the answer for me was to put the singleton in a separate class or manually initialize the static data in the instance constructor before it is required)

Prosciutto answered 28/7, 2018 at 9:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.