Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order of static constructors/initializers in C#

While working on a C# app I just noticed that in several places static initializers have dependencies on each other like this:

static private List<int> a = new List<int>() { 0 }; static private List<int> b = new List<int>() { a[0] }; 

Without doing anything special that worked. Is that just luck? Does C# have rules to resolve this?

Edit: (re: Panos) In a file lexical order seems to be king? what about across files?

In looking I tried a cyclical dependency like this:

static private List<int> a = new List<int>() { b[0] }; static private List<int> b = new List<int>() { a[0] }; 

and the program didn't run the same (the test suit failed across the board and I didn't look further).

like image 841
BCS Avatar asked Oct 08 '08 23:10

BCS


People also ask

Why static constructor is called first?

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

Which constructor is called first in C# static or default?

That's why you can see in the output that Static Constructor is called first. Times of Execution: A static constructor will always execute once in the entire life cycle of a class. But a non-static constructor can execute zero time if no instance of the class is created and n times if the n instances are created.

How many static constructors are allowed in a class C#?

A class or struct can only have one static constructor. Static constructors cannot be inherited or overloaded. A static constructor cannot be called directly and is only meant to be called by the common language runtime (CLR). It is invoked automatically.

Why static constructor is Parameterless in C#?

When a data member is shared among different instances it is imperative that data should be consistent among all the instances of the class. And also there is no way to call static constructor explicitly. Therefore the purpose of having a parameterized static constructor is useless.


1 Answers

See section 10.4 of the C# spec for the rules here:

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. Likewise, when an instance of a class is created, all instance fields in that instance are first initialized to their default values, and then the instance field initializers are executed in textual order. It is possible for static fields with variable initializers to be observed in their default value state. However, this is strongly discouraged as a matter of style.

So in other words, in your example 'b' is initialized to its default state (null) and so the reference to it in the initializer of 'a' is legal but would result in a NullReferenceException.

These rules are different to Java's (see section 8.3.2.3 of the JLS for Java's rules about forward references, which are more restrictive).

like image 62
Cowan Avatar answered Sep 17 '22 20:09

Cowan