private class StaticInitTester
{
static StaticInitTester() {
}
private StaticInitTester()
{
var isNotNull = _mappingFunc != null ? "not" : "";
Console.WriteLine($"mapping func is {isNotNull} null");
}
public static StaticInitTester Instance { get; } = new StaticInitTester();
private static readonly Func<string, string> _mappingFunc = s => s.ToString();
}
[TestMethod]
public void TestStaticInitialization()
{
Console.WriteLine(StaticInitTester.Instance);
}
输出实际上是"映射函数为空";
这让我很惊讶,因为我认为所有静态初始化都应该在StaticInitTester的非静态构造函数中完成一次。当我移动线路时-
私有静态只读Func<字符串,字符串>_mappingFunc=s=>s.ToString((;
到了班上的第一名,我就得到了
"映射函数不为空";
因此,这条线的位置似乎正在影响结果。
这种行为有记录吗?对这种行为有什么解释?
是的,有文档记录。来自规范:
类的静态字段变量初始值设定项对应于一系列赋值,这些赋值按它们在类声明中出现的文本顺序执行。如果类中存在静态构造函数(静态构造函数(,则在执行该静态构造函数之前立即执行静态字段初始值设定项。
因此,因为Instance
在_mappingFunc
之前声明(按文本顺序(,所以它在分配_mappingFunc
之前被分配(并调用StaticInitTester
ctor(,这导致了观察到的行为。