发现一段很诡异的C#代码,见识了静态构造函数这种奇怪的东西: 

C#代码  收藏代码
  1. using System;  
  2.   
  3. namespace StaticTest  
  4. {  
  5.     class A  
  6.     {  
  7.         public static int X;  
  8.         static A()  
  9.         {  
  10.             X = B.Y + 1;  
  11.         }  
  12.     }  
  13.     class B  
  14.     {  
  15.         public static int Y = A.X + 1;  
  16.         static B()  
  17.         {  
  18.         }  
  19.         static void Main()  
  20.         {  
  21.             Console.WriteLine("X={0}, Y={1}", A.X, B.Y);  
  22.         }  
  23.     }  
  24. }  



先补习下吧: 

  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的值……啊,要疯掉了……应该是多少呢?不敢确定了吧,交给编译器来运行看看吧~~ 
结果如下: 

Java代码  收藏代码
  1. X=1, Y=2  



修改下代码,看看内部到底怎么运行的: 

C#代码  收藏代码
  1. using System;  
  2.   
  3. namespace StaticTest  
  4. {  
  5.     class A  
  6.     {  
  7.         public static int X;  
  8.         static A()  
  9.         {  
  10.             Console.WriteLine("calling A");  
  11.             Console.WriteLine(B.Y);  
  12.             X = B.Y + 1;  
  13.         }  
  14.     }  
  15.     class B  
  16.     {  
  17.         public static int Y = A.X + 1;  
  18.         static B()  
  19.         {  
  20.             Console.WriteLine("calling B");  
  21.             Console.WriteLine(Y);  
  22.         }  
  23.         static void Main()  
  24.         {  
  25.             Console.WriteLine("X={0}, Y={1}", A.X, B.Y);  
  26.         }  
  27.     }  
  28. }  


执行结果如下: 

Java代码  收藏代码
  1. calling A  
  2. 0  
  3. calling B  
  4. 2  
  5. X=1, Y=2  


看到这个结果,对C#更加迷惑了。类A中静态构造函数调用得到的B.Y,居然是0。这是什么道理?难道这个时候B还没出生,但是B.Y已经出生了?不管了,先接受了吧,以后玩C#还是小心点了。哪位神仙指点指点迷津啊? 

posted on 2014-06-25 17:21  GC2013  阅读(1823)  评论(6编辑  收藏  举报