Understanding Static Constructor, 理解静态构造函数
引言:
想起这个问题是一次面试提到的题目而起,而之前也有关于静态构造函数和构造函数区别, 于是有了这次探索.
用法:
1. 初始化静态成员数据
1: public class MyTest
2: {
3: static string Str = "This is MyTest";
4: static int i = 0;
5:
6: static MyTest()
7: {
8: Str = "Hi, I am Initialized";
9: i++;
10: }
11: }
2. 初始化静态readonly成员
1: public class MyTest
2: {
3: static readonly string MyReadonlyData = "MyTest's MyReadonlyData";
4:
5: static MyTest()
6: {
7: MyReadonlyData = ":), Has been modifyed in static contructor";
8: }
9: }
实现层次:
对应的il代码结构, 所谓cctor, 是类中定义初始化数据的方法
在.Net对于赋值操作又分为两种方式
- precise
- beforefieldinit
precise 执行方式
1: public class AnotherTest
2: {
3: static AnotherTest() {
4:
5: }
6: public static string Test = "This is a test from another test";
7: }
beforefieldinit
1: public class AnotherTest
2: {
3: public static string Test = "This is a test from another test";
4: }
所谓beforefieldinit是指在数据被调用前初始化数据.
至于il代码,也是在class定义时添加了一个beforefieldinit标记, 在初始化数据时于是我们建议使用constructor chain来初始化数据,所谓constrcutor chain:
1: namespace XWang
2: {
3: public class Test
4: {
5: int A;
6: int B;
7: int C;
8: string InitialConfigurations;
9:
10: // The Constructor to initialize the private datas
11: public Test()
12: {
13: B = 2;
14: C = 3;
15: }
16:
17: // Initalize the a and call the default parameterless constructor
18: public Test(int a) : this()
19: {
20: A = a;
21: }
22:
23: // A Constructor Chain to initialize the datas
24: public Test(string configuration, int a): this(a)
25: {
26: InitialConfigurations = configuration;
27: }
28: }
29: }
对于静态构造函数,我们也应该在静态构造函数中初始化数据
1: namespace XWang
2: {
3: public class StaticConstructorTest
4: {
5: static string StaticData;
6:
7: static StaticConstructorTest()
8: {
9: StaticData = "Hi, I am initialized";
10: }
11: }
12: }
同时这也是Effective C#中提到的其中几个原则:
- 条款12:变量初始化器优于赋值语句
- 条款13:使用静态构造器初始化静态类成员
- 条款14:利用构造器链
Have Fun :)