【发布时间】:2015-07-27 17:27:39
【问题描述】:
嵌套静态类在其父级之前初始化似乎存在问题。请参阅下面的示例,我已经包含 cmets 来指示我期望的东西被初始化/调用的顺序,以及实际的顺序。在这种情况下,我调用Test1.Test2.GetName(),所以我希望静态类按以下顺序初始化:Test1,Test2
using System;
using System.Collections.Generic;
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
Console.WriteLine(Test1.Test2.GetName());
Console.ReadKey();
}
}
public static class Test1 {
// Actual Order: 2; Expected: 1
private static string Name = "Test1";
public static List<string> Names { get; private set; }
// Actual Order: 3; Expected: 2
static Test1() {
Test1.Names = new List<string>(new string[] {
Test2.GetName()
});
}
public static class Test2 {
// Actual Order: 1; Expected: 3
private static string Name = Test1.Name.ToString() + "_Test2";
// Actual Order: 4; Expected: 4
public static string GetName() {
return Name.ToString();
}
}
}
}
我认为静态是在第一次接触类时初始化的,但显然接触嵌套类并没有首先初始化父类!这对我来说就像一个错误。它正在这样做:
Test2.Name -> Test1.Name -> Test1() -> Test2.GetName() -> Test2.Name
所以虽然Test2.Name是入口点,但理论上它并没有在需要的时候初始化。
【问题讨论】:
-
在the literature 中得到了很好的覆盖。引用:“用户无法控制何时在程序中执行静态构造函数”。换句话说,顺序不是“错误的”,而是未定义的。
-
它还说“在创建第一个实例或引用任何静态成员之前自动调用”这在这种情况下是不正确的,因为嵌套的静态类首先被初始化!我不希望有控制权,但我应该能够假设这会发生的顺序。
-
您应该改用初始化方法。这样你就可以控制初始化。在最坏的情况下,您可以从 Program 中的静态构造函数初始化它们。
-
这是我作为解决方法所做的,但这仍然感觉像是编译器中的一个错误。