Initialization order for static fields

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Does .NET provide any guarantees as to the order in which static fields are
initialized? E.g. Sample 1 below appears to work as expected because
_myObject is initialized before InitializeSomeType() is called. Sample 2
throws a NullReferenceException because _myObject is not yet initialized when
InitializeSomeType() is called.

It appears that static fields are initialized in the order they appear in
the source file, but is this guaranteed?

----- Sample 1 -----
public class MyClass
{
private static object _myObject = new object();
private static SomeType _mySomeType = InitializeSomeType();

private static InitializeSomeType()
{
lock(_myObject)
{
...
}
}
}

----- Sample 2 -----
public class MyClass
{
private static SomeType _mySomeType = InitializeSomeType();
private static object _myObject = new object();

private static InitializeSomeType()
{
lock(_myObject)
{
...
}
}
}
 
Joe said:
Does .NET provide any guarantees as to the order in which static fields are
initialized? E.g. Sample 1 below appears to work as expected because
_myObject is initialized before InitializeSomeType() is called. Sample 2
throws a NullReferenceException because _myObject is not yet initialized when
InitializeSomeType() is called.

It's actually C# which provides the ordering - .NET just executes the
type initializer.

C# fortunately does make a guarantee here:

<quote>
Thus, when a class is initialized, all static fields in that class are
first initialized to their default values, and then the static field
initializers are executed in textual order.
</quote>
 
Looking at the generated IL you will see that the compiler generates a static
constructor for the class (cctor) in which it initializes the static fields
in the order they are declared and initialized in the C# code.

Regards, Jakob.
 
Jon, Jakob, thanks for the responses.

It's interesting that the generated IL has a static constructor: in this
case why does FxCop 1.30 have a rule DoNotDeclareExplicitStaticConstructors
(Initializing static data in explicit static constructors results in less
performant code)? The FxCop documentation doesn't say why.
 
Joe said:
Jon, Jakob, thanks for the responses.

It's interesting that the generated IL has a static constructor: in this
case why does FxCop 1.30 have a rule DoNotDeclareExplicitStaticConstructors
(Initializing static data in explicit static constructors results in less
performant code)? The FxCop documentation doesn't say why.

There's a difference between a static constructor (which is a C# term)
and a type initializer (which is a CLR term).

Whenever you do any initialization of static variables, you end up with
a type initializer. You only get a static constructor if you declare
one in your code. The code gets put into the type initializer, and
(importantly) the beforefieldinit flag isn't set, which it otherwise
is. That's what affects performance.

See http://www.pobox.com/~skeet/csharp/beforefieldinit.html for more
information.
 
Back
Top