Search code examples
c#staticstatic-initialization

Static member initialization order within a single C# class


Consider the following class snippet with two static member variables:

            public static class Foo
            {

                static string A = GetA(B);
                static string B = "required for A";
                ...

Now, my understanding is that A and B will be initialized when they are accessed for the first time. However, when I executed a fully-realized version of the snippet above where A was accessed before B was initialized, it led to null being passed in to GetA() instead of "required for A". Why isn't the behaviour to start initializing A, then, when it's realized that B is required to initialize A, initialize B, then return to finish the initialization of A?

What are the general rules around this? Why does it behave this way? I've seen other questions that touch on this (When do static variables get initialized in C#?) but they don't answer this question exactly. What is the static variable initialization order in C#? talks primarily about how this works across classes, not within a single class (though Jon Skeet's addendum to his answer -- "By popular demand, here was my original answer when I thought the question was about the initialization order of static variables within a class:...." does answer this question, it's buried in a much longer answer).


Solution

  • In short, don't do this.

    Standard ECMA-334 C# Language Specification

    15.5.6.2 Static field initialization

    The static field variable initializers of a class correspond to a sequence of assignments that are executed in the textual order in which they appear in the class declaration (§15.5.6.1). Within a partial class, the meaning of "textual order" is specified by §15.5.6.1. If a static constructor (§15.12) exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class

    The fix is to :

    • Put them in the order and use Static Constructor,
    • or just Initialise them in a Static Constructor in turn giving you the ability to control the order of initialisation (given the above information).

    Personally i suggest to Initialise them in a Static Constructor, it seems to make it more concrete and understandable, and less likely to be bumped in refactoring