Alex Rivera | Logout

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

Asked 2009-09-10T14:43:24.993
11

DependencyProperty.AddOwner MSDN page offers an example with two classes with static members, and the member of one class depends on the member of the other class for initialization. I think MSDN is wrong - the initialization order of static variables is unreliable in C# just like it is in C++ or anywhere else. I'm probably wrong because the WPF library itself is written that way and it works just fine. What am I missing? How can C# compiler possibly know the safe initialization order?

Edit
Report

2 Answers

28

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

answered 2009-09-10T14:47:04.080
0

If you are concerned about the order you could always place your code in the static constructor. This is where I register my dependency properties.

answered 2009-09-10T14:49:02.610

Your Answer