When Do Static Variables Get Initialized in C#

When do static variables get initialized in C#?

Oh, that is complex. It depends on whether the beforefieldinit flag is set, which in turn (in C#) depends on whether there is a static constructor. And worse; in .NET 4 I believe the behaviour changed to make it more "lazy" than it used to be.

Frankly, I wouldn't code to any specific behaviour here; simply: static fields will be initialized before you try to use them, as long as you use regular code to access them.

Jon Skeet has a good write-up on this here and here

In C#, do all static variables get initialized before the main() method is called?

according to C# spec which says:

If a static constructor 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 example

whiteout a static constructor you can not predict exactly when a static variable is initialized but they are guaranteed to be initialized before their first use. but for sure they are not initialized before you reference their assemblies

What is the static variable initialization order across classes in C#?

It's fine for one type to depend on another type being initialized, so long as you don't end up in a cycle.

Basically this is fine:

public class Child
{
static Child() {} // Added static constructor for extra predictability
public static readonly int X = 10;
}

public class Parent
{
static Parent() {} // Added static constructor for extra predictability
public static readonly int Y = Child.X;
}

The result is well-defined. Child's static variable initializers are executed prior to the first access to any static field in the class, as per section 10.5.5.1 of the spec.

This isn't though:

public class Child
{
public static readonly int Nasty = Parent.Y;
public static readonly int X = 10;
}

public class Parent
{
public static readonly int Y = Child.X;
}

In this latter case, you either end up with Child.Nasty=0, Parent.Y=10, Child.X=10 or Child.Nasty=0, Parent.Y=0, Child.X=10 depending on which class is accessed first.

Accessing Parent.Y first will start initializing Parent first, which triggers the initialization of Child. The initialization of Child will realise that Parent needs to be initialized, but the CLR knows that it's already being initialized, so carries on regardless, leading to the first set of numbers - because Child.X ends up being initialized before its value is used for Parent.Y.

Accessing Child.Nasty will start initializing Child first, which will then start to initialize Parent. The initialization of Parent will realise that Child needs to be initialized, but the CLR knows that it's already being initialized, so carries on regardless, leading to the second set of numbers.

Don't do this.


EDIT: Okay, more detailed explanation, as promised.

When is a type initialized?

If a type has a static constructor, it will only be initialized
when it's first used (either when a static member is referenced, or
when an instance is created). If it doesn't have a static
constructor, it can be initialized earlier. In theory, it could also
be initialized later; you could theoretically call a constructor or
a static method without the static variables being initialized - but
it must be initialized before static variables are referenced.

What happens during initialization?

First, all static variables receive their default values (0, null
etc).

Then the static variables of the type are initialized in textual
order. If the initializer expression for a static variable requires
another type to be initialized, then that other type will be
completely initialized before the variable's value is assigned -
unless that second type is already being initialized (due to a
cyclic dependency). Essentially, a type is either:

  • Already initialized
  • Being initialized at the moment
  • Not initialized

Initialization is only triggered if the type is not initialized.
This means that when there are cyclic dependencies, it is possible
to observe a static variable's value before its initial value has
been assigned
. That's what my Child/Parent example shows.

After all the static variable initializers have executed, the static
constructor executes.

See section 10.12 of the C# spec for more details on all of this.


By popular demand, here was my original answer when I thought the question was about the initialization order of static variables within a class:

Static variables are initialized in textual order, as per section 10.5.5.1 of the C# spec:

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.

Note that partial types make this trickier as there's no one canonical "textual order" of the class.

c# initialize static variable from different classes

This is because the static constructor is called automatically before the first instance is created or any static members are referenced..

This means that when an instance of otherClass invokes IDs.someID = sym; the first operation that gets executed is the static constructor, i.e. the code inside static IDs().

At this point the static variable has not yet been initialized, and you are basically executing log.info(null);.

After the static constructor completes, the variable is initialized, so you should be able to see its value inside otherMethod, after the first reference of IDs.


Given the OP's requirement:

I want to use the value passed in someID in a switch statement

The solution could be to simply execute a static method whenever a new value is set, with the help of explicit getters and setters:

public static class IDs
{
private static string _someID; // backing field

public static string SomeID
{
get { return _someID; }

set
{
_someID = value;
DoSomethingWithSomeID();
}
}

private static DoSomethingWithSomeID()
{
// Use SomeID here.

switch (IDs.SomeID)
{
...
}
}
}

public class OtherClass
{
public void OtherMethod(string sym)
{
// This will set a new value to the property
// and invoke DoSomethingWithSomeID.
IDs.SomeID = sym;
}
}

DoSomethingWithSomeID will be invoked every time someone sets a new value to SomeID.

Static member initialization order within a single C# class

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

What is the advantage of initializing static variable in a static constructor instead of direct assignment of value

they will be compiled in to same thing. so no difference,

That's not private constructor. that's static constructor

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

I use static constructor when by directly assigning value, the line becomes too long (that's opinion based) or when I need multiple lines to initialize a value.

Are static variables initialized in any particular thread?

In C#, static variables are initialized by the class loader when the class is first loaded. This has the interesting artifact of being on whatever thread first referenced the class.

We also note that the main thread is not guaranteed to be a managed thread, so any library after the main thread isn't quite guaranteed to be able to identify it. I wrote a program once that had no main thread after native initialization just to prove it could be done.

How come static variable is usable even before it is declared in C#

From ECMA-334 - 17.4.5.1 Static field initialization

The static field variable initializers of a class declaration
correspond to a sequence of assignments that are executed in the
textual order in which they appear in the class declaration. If a
static constructor (§17.11) 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
.

So y variable is used in the line of initialization of x variable and get initialized with default value which is 0



Related Topics



Leave a reply



Submit