发现一段很诡异的C#代码,见识了静态构造函数这种奇怪的东西:
- using System;
- namespace StaticTest
- {
- class A
- {
- public static int X;
- static A()
- {
- X = B.Y + 1;
- }
- }
- class B
- {
- public static int Y = A.X + 1;
- static B()
- {
- }
- static void Main()
- {
- Console.WriteLine("X={0}, Y={1}", A.X, B.Y);
- }
- }
- }
先补习下吧:
1、静态构造函数既没有访问修饰符,也没有参数。因为是.NET调用的,所以像public和private等修饰符就没有意义了。
2、是在创建第一个类实例或任何静态成员被引用时,.NET将自动调用静态构造函数来初始化类,也就是说我们无法直接调用静态构造函数,也就无法控制什么时候执行静态构造函数了。
3、一个类只能有一个静态构造函数。
4、无参数的构造函数可以与静态构造函数共存。尽管参数列表相同,但一个属于类,一个属于实例,所以不会冲突。
5、最多只运行一次。
6、静态构造函数不可以被继承。
7、如果没有写静态构造函数,而类中包含带有初始值设定的静态成员,那么编译器会自动生成默认的静态构造函数。
好,复习完毕,哪位同学回答下上面程序的输出结果是多少?
还是搞不明白吧:) 唔,你明白了?他没明白,我也没明白……
class A静态构造函数中的B.Y好像很奇怪,貌似要确定A.X的值,得先确定B.Y的值,而B.Y的值在B中却是由A.X来确定的,那A.X的值……啊,要疯掉了……应该是多少呢?不敢确定了吧,交给编译器来运行看看吧~~
结果如下:
- X=1, Y=2
修改下代码,看看内部到底怎么运行的:
- using System;
- namespace StaticTest
- {
- class A
- {
- public static int X;
- static A()
- {
- Console.WriteLine("calling A");
- Console.WriteLine(B.Y);
- X = B.Y + 1;
- }
- }
- class B
- {
- public static int Y = A.X + 1;
- static B()
- {
- Console.WriteLine("calling B");
- Console.WriteLine(Y);
- }
- static void Main()
- {
- Console.WriteLine("X={0}, Y={1}", A.X, B.Y);
- }
- }
- }
执行结果如下:
- calling A
- 0
- calling B
- 2
- X=1, Y=2
看到这个结果,对C#更加迷惑了。类A中静态构造函数调用得到的B.Y,居然是0。这是什么道理?难道这个时候B还没出生,但是B.Y已经出生了?不管了,先接受了吧,以后玩C#还是小心点了。哪位神仙指点指点迷津啊?