It seems to depend on the sequence of lines. This code works:
static private List<int> a = new List<int>() { 1 };
static private List<int> b = new List<int>() { a[0] };
while this code does not work (it throws a NullReferenceException
)
static private List<int> a = new List<int>() { b[0] };
static private List<int> b = new List<int>() { 1 };
So, obviously no rules for cyclical dependency exist. It's peculiar however that the compiler does not complain...
EDIT - What's happening "across files"? If we declare these two classes:
public class A {
public static List<int> a = new List<int>() { B.b[0] };
}
public class B {
public static List<int> b = new List<int>() { A.a[0] };
}
and try to access them with this code:
try { Console.WriteLine(B.b); } catch (Exception e) { Console.WriteLine(e.InnerException.Message.); }
try { Console.WriteLine(A.a); } catch (Exception e) { Console.WriteLine(e.InnerException.Message); }
try { Console.WriteLine(B.b); } catch (Exception e) { Console.WriteLine(e.InnerException.Message); }
we are getting this output:
The type initializer for 'A' threw an exception.
Object reference not set to an instance of an object.
The type initializer for 'A' threw an exception.
So the initialization of B
causes an exception in static constructor A
and lefts field a
with the default value (null). Since a
is null
, b
can not also be initialized properly.
If we do not have cyclical dependencies, everything works fine.
EDIT: Just in case you didn't read the comments, Jon Skeet provides a very interesting reading: The differences between static constructors and type initializers.