它似乎取决于行的顺序。此代码有效:
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
由于a
is null
,b
也不能正确初始化。
如果我们没有循环依赖,那么一切正常。
编辑:以防万一您没有阅读评论,Jon Skeet提供了一个非常有趣的阅读:静态构造函数和类型初始化程序之间的区别。