预期产量&输出我进入调试模式,并在VS2010,.NET 4.0下发布模式:
bar construct
main
在VS2010调试器下的发布模式 不 下输出,并在WinDbg下输出:
main
程序在VS2005,.NET 2.0上没有出现此行为
using System;
namespace static_init
{
public class bar
{
public bar()
{
Console.WriteLine("bar construct");
}
}
class Program
{
public static bar blah = new bar();
static void Main(string[] args)
{
Console.WriteLine("main");
Console.ReadLine();
}
}
}
可能相关: Static constructor can run after the non-static constructor. Is this a compiler bug?
更新
在我的实际代码构造函数bar()
中使用C ++(非托管)初始化一些互操作代码。它需要在此库中的任何其他内容之前发生 - 是否有任何方法可以确保在没有放入init()
函数的情况下触及库中的所有静态(具有未外部引用的副作用)? / p>
未来搜索者的注意事项:我正在使用SWIG,这是他们在包装器生成代码中做出的假设。 SWIGStringHelper
是当前的罪犯,但可能会有更多。
结论
更新到SWIG 2.0版,它根据新版.NET的需要放入静态构造函数。
答案 0 :(得分:10)
它可能已经过优化,因为你没有使用它。
它也不是编译器错误,它在语言规范中。
17.4.5.1 静态字段初始化
静态字段变量初始值设定项 类声明对应于a 分配顺序 以文字顺序执行 它们出现在类声明中。 如果是静态构造函数(第17.11节) 存在于类中,执行 发生静态字段初始化程序 在执行之前 静态构造函数。否则, 执行静态字段初始值设定项 在依赖于实现的时间 在第一次使用静电之前 该类的领域
由于您从不使用Program类的静态字段,因此无法保证静态初始值设定项运行(尽管它可能......上面的'实现相关时间')
<强>更新强>
您可以通过使程序具有静态构造函数来完成您想要的任务。
static Program (){}
或者可能通过访问另一个(可能是虚拟的)静态变量
答案 1 :(得分:7)
请注意,.NET 4.0中有一些关于静态初始化的更改。 Jon Skeet撰写了一篇博文,内容包括一些样本:
如果要进行精确初始化,则应使用静态构造函数(可能为空)。
using System;
namespace static_init
{
public class bar
{
public bar()
{
Console.WriteLine("bar construct");
}
}
class Program
{
public static bar blah = new bar();
// This static constructor will make sure that the type Program
// is initialized before it is first used.
//
static Program()
{ }
static void Main(string[] args)
{
Console.WriteLine("main");
Console.ReadLine();
}
}
}