它似乎取决于行的顺序。此代码有效:
static private List<int> a = new List<int>() { 1 };
static private List<int> b = new List<int>() { a[0] };
虽然这段代码不起作用(它抛出一个NullReferenceException)
static private List<int> a = new List<int>() { b[0] };
static private List<int> b = new List<int>() { 1 };
因此,显然不存在周期性依赖的规则。然而,编译器没有抱怨是很奇怪的......
编辑 - “跨文件”发生了什么?如果我们声明这两个类:
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] };
}
并尝试使用以下代码访问它们:
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); }
我们得到这个输出:
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.
因此,初始化B会导致静态构造函数中的异常,并使用默认值(null)A留下字段。a由于ais null,b也不能正确初始化。
如果我们没有循环依赖,那么一切正常。
编辑:以防万一您没有阅读评论,Jon Skeet提供了一个非常有趣的阅读:静态构造函数和类型初始化程序之间的区别。