using System;
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);
}
}
请大家帮忙分析这段代码是如何运行的,结果是:X=1,Y=2。
我不知道为什么。
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);
}
}
请大家帮忙分析这段代码是如何运行的,结果是:X=1,Y=2。
我不知道为什么。
答案是:X=2,Y=1
解释(来自于网上):
1.其实关于静态构造函数的题目,以前也见过,主要是考察静态构造函数和构造函数执行先后顺序的理解。这道题目倒是别出心裁,升级成了两个类型的静态构造函数和静态成员初始化执行先后顺序。
我们都知道静态成员初始化和静态构造函数编译后都是静态构造函数的一部分,而静态构造函数在类型被加载时执行,这道题目的头疼之处在于,并不是很明显能看出到底是A类加载在前还是B类加载在前。如果A类加载在前,则执行A类的静态构造函数的时候,必然会加载B类型,换言之在B.Y + 1这个表达式有结果前,B类型必须被加载,所以Y = 0(X默认为零) + 1 = 1,X = 1(Y被初始化) + 1 = 2。如果B类初始化在前,则结果恰恰相反。最后我认为A类将加载在前,结果应该是X=2,Y=1。但实际上心里并没底。——Ivony(出自:这里)
2.Main方法是程序的入口,Console.WriteLine( "X={0},Y={1}", A.X, B.Y );中先访问的是A.X,因为X是静态的成员所以在访问X之前A的静态构造函数必定已经执行完成,A的静态构造函数中又访问了B.X,同理在A的静态构造函数中获得B.Y的值之前B的静态构造函数必定已经执行完成,由于在完成A的静态构造函数中X=B.Y + 1的中途中执行流程跳到了B的静态构造函数,所以此时A.X还是默认值0,接着在B的静态构造函数被执行完成后得以在A的静态函数中成功获得B.Y,此时B.Y=A.X + 1=0+1=1,接着A.X=1+1=2
所以输出的是X=2,Y=1
我有次面试也遇到这个题目,我给出个结果后面自己注释了个“//不肯定”因为脑子被搞乱了,面试官看了答的结果后问我为什么,因为我可能是蒙对了,我承认了输出结果我是蒙的,但是我用自己知道的关于静态方法的知识回答了他问的为什么的问题,我用了正确的执行流程在大脑中执行了这个过程,但是由于当时很紧张并不能肯定自己执行出的结果。
——Xuefly(出自这里)
http://topic.csdn.net/u/20100402/13/222c8fa7-0598-4834-95e9-51a57fb8f94b.html?87042
另外,静态变量(整型)只要申明了就会被初始化为0。
-----有了上面的知识就可以来分析代码了,
Console.WriteLine("X={0},Y={1}",A.X,B.Y);
先调用到A.X, 于是调用A的静态构造函数,于是执行到X=B.Y+1;此时B.Y=0(刚才说过,静态变量被初始化为0),所以X=B.Y+1=0+1=1. 然后执行到了要取B.Y的值,于是执行到B的静态构造函数, Y=A.X+1;由于此时A.X已经由之前的A的构造函数赋值为1了,所以B.Y=A.X+1=1+1=2。解释完毕。
http://topic.csdn.net/u/20071224/10/29a460d6-f6fc-4f83-b285-d3237eccd4ff.html
一:这个结果是执行完Console.WriteLine("X={0},Y={1}",A.X,B.Y);
中的A.X后的结果,等执行B.Y时,Y应该就等于3了。
二:代码运行的结果是X=1,Y=2。
经过实验证明这个解释是正确的,但是有一点需要说明的就是:
在A的静态构造函数中调用B.Y时,是没有去调用B的静态构造函数的,而是直接使用了B.Y的初始值0。
-------------
恩,这里有点奇怪,照道理来说彭到B.Y,应该去调用B的静态构造函数,但是这样很可能造成死循环,所以静态构造函数不会触发相互调用。