我试图了解何时出现了完全静态的字段并且已经阅读了这篇MSDN文章 - http://msdn.microsoft.com/en-us/library/79b3xss3 - 但它似乎与自己相矛盾:
首先它说:
静态成员在第一次访问静态成员之前和静态构造函数(如果有的话)之前被初始化。
然后接着说:
如果您的类包含静态字段,请提供一个静态构造函数,以便在加载类时初始化它们。
所以,我的问题基本上是这样的:什么时候静态字段实际初始化,什么时候它们首先出现?是在静态构造函数被调用之前,期间还是之后?
非常感谢!
答案 0 :(得分:9)
C#语言规范声明(在10.5.5.1 Static field initialization
中):
类的静态字段变量初始值设定项对应于按照它们出现在类声明中的文本顺序执行的赋值序列。如果类中存在静态构造函数(第10.12节),则在执行该静态构造函数之前立即执行静态字段初始值设定项。否则,静态字段初始值设定项在首次使用该类的静态字段之前的实现相关时间执行
我相信第二行中的指导实际上是使用字段初始值设定项初始化未内联完成的静态字段。在这种情况下,您应该使用静态构造函数来保证在使用之前对它们进行初始化。
从规范中可以看出,它们产生的实际“时间”是特定于实现的,并且可能会发生变化。唯一的保证是它们将在调用静态构造函数之前存在,它将始终在代码中使用之前发生。该规范陈述(在10.12中):
静态构造函数的执行由应用程序域中发生的以下第一个事件触发:
·创建了类类型的实例。
·引用了类类型的任何静态成员。
答案 1 :(得分:2)
这就像“正常”字段。所以在静态构造函数之前。你可以用一个非常简单的程序来检查。
订单是:
示例程序:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Start");
int b = A.B;
Console.WriteLine("Read A.B");
new A();
Console.WriteLine("Built A");
}
}
class A
{
public static int B = mystaticfunc();
static int mystaticfunc() {
Console.WriteLine("Static field");
return 1;
}
static A()
{
Console.WriteLine("Static constructor");
}
int C = myfunc();
static int myfunc()
{
Console.WriteLine("Field");
return 1;
}
public A()
{
Console.WriteLine("Constructor");
}
}
输出:
Start
Static field
Static constructor
Read A.B
Field
Constructor
Built A
答案 2 :(得分:1)
保证在第一次使用该类之前初始化静态字段。
可选地,您可以提供静态构造函数来控制静态初始化。
答案 3 :(得分:1)
CLR没有静态成员初始化和静态构造函数的单独概念。相反,只有一个类型的初始化程序。
C#编译器为您编写此类型初始化程序,首先它执行静态成员的初始化,然后它包含您定义的任何静态构造函数的代码。