是否应该在调用构造函数之前完成静态字段初始化?
下面的程序提供的输出在我看来是不正确的。
new A()
_A == null
static A()
new A()
_A == A
代码:
public class A
{
public static string _A = (new A()).I();
public A()
{
Console.WriteLine("new A()");
if (_A == null)
Console.WriteLine("_A == null");
else
Console.WriteLine("_A == " + _A);
}
static A()
{
Console.WriteLine("static A()");
}
public string I()
{
return "A";
}
}
class Program
{
static void Main(string[] args)
{
var a = new A();
}
}
发布于 2009-04-02 17:40:29
这是正确的。
静态构造器,然后静态构造器在标准构造器之前运行,但当它运行时,它使用新的A(),因此通过非静态构造器路径传递。这会导致您看到的消息。
下面是执行的完整路径:
当您第一次在程序中调用var a = new A();
时,这是第一次访问A。
这将触发A._A
的静态初始化
此时,A._A使用_A = (new A()).I();
进行构造
这个命中了
Console.WriteLine("new A()");
if (_A == null)
Console.WriteLine("_A == null");
因为在这一点上,_A还没有设置为返回的构造类型(还没有)。
接下来,运行静态构造函数A { static A(); }
。这将打印"static A()“消息。
最后,执行原始语句(var a = new A();
),但此时构造了静态语句,因此得到了最终的打印结果。
发布于 2009-04-02 17:46:19
我真的相信它是在做你认为的事情。你的测试让人很难判断。
您对_A的初始化
public static string _A = (new A()).I();
首先创建一个新的A实例,因此您编写的新A()和_A = null。因为它在启动时是null,因为这是初始化。初始化后,将调用静态构造函数,该函数将返回新实例。
发布于 2009-04-02 17:45:43
是的,静态字段初始化应该在调用构造函数之前完成。但是你把编译器放在不正常的情况下,它就不能遵守这个规则。
这是一个有趣的技巧,但它不会在正常的应用程序中发生。
https://stackoverflow.com/questions/710793
复制相似问题