日期:2014-05-18  浏览次数:20749 次

静态类静态构造函数 静态变量 执行顺序问题 谁帮忙解释下
C# code

using System;

namespace CSharpTest
{
    static class A
    {
        public static int x;
        static  A()
        {
            x=B.y+1;
             
        } 
    }
    static class B 
    {
        public static int y=A.x+1;
        static B() 
        {
        }
        static void Main()
        {
            Console.WriteLine("x={0}  y={1}",A.x,B.y);
        }
    }
}



执行结果 
x=1 y=2
谁帮忙解释下怎么执行的

------解决方案--------------------
类(包括静态类)可以有静态构造函数。在程序开始和实例化类之间的某个时刻调用静态构造函数。
------解决方案--------------------
我单步跟踪的结果是:先跳到public static int y=A.x+1;这句,然后跳到A(),这时y仍然等于0,然后跳回public static int y=A.x+1;最后跳到Console.WriteLine
所以我的理解是先初始静态变量,然后再是静态构造函数。上面因为B类有Main方法,所以先初始y。
上面的例子,先初始y,但是y的值从A.x得来,所以访问构造函数A(),这时尚未访问构造函数B(),所以y还未初始化,取缺省值0。如果把y的类型改成int?,就会发现这时y的值是null。

当然,这个例子的实用意义可能不大。

另外,昨天碰巧看了这个帖子:

http://geekswithblogs.net/BlackRabbitCoder/archive/2010/05/19/c-system.lazylttgt-and-the-singleton-design-pattern.aspx

里面提到,IL自动给静态类加上BeforeFieldInit属性,这样,静态成员可能在任何时候被初始化。但是,如果有个静态的构造函数,这个属性就不加了,这样可以保证静态成员在第一次被调用时初始化。这个知识也有点参考价值。

------解决方案--------------------
楼主,你把
static void Main()
 {
Console.WriteLine("x={0} y={1}",A.x,B.y);
 }
从B里面拿出来,放到一个不想干的位置.
不然的话,调用Main之前就会初始化B,
调用顺序是这样的
B.y
A.x
A()
B.y <-注意,此时这个值是0

然后在Main方法调用之前 A.x=1,B.Y=2.

------解决方案--------------------
我怎么都觉得你这是在调戏.net 嵌套引用看的郁闷 没什么意义
------解决方案--------------------
main函数在B里面,所以编译器首先是初始化B
首先是字段Y,Y是int型,编译器初始化为0 ,然后Y为static,所以编译器接着执行B的静态构造函数,注意一点,构造函数只执行一次
在static B()里面,Y被赋值为A.X+1,编译器接着去找A.X的值,此时执行A的静态构造函数,x=B.Y+1,因为B的构造函数已经执行了,此时就不执行第二次,Y此时具有
值是0,所以X=1;然后返回Y=A.X+1,Y=2
所以答案就是X=1;Y=2;

注意两点就可以了:初始化顺序是先字段后构造函数,每个字段都有一个初始的默认值
------解决方案--------------------
类(包括静态类)可以有静态构造函数。在程序开始和实例化类之间的某个时刻调用静态构造函数。