在Release - Compiler/clr bug中没有初始化静态成员变量?

Zac*_*Zac 6 c# clr .net-4.0

预期的输出和输出我进入调试模式,并在VS2010,.NET 4.0下发布模式:

bar construct
main
Run Code Online (Sandbox Code Playgroud)

输出在释放模式没有在VS2010的调试器,并且在WinDbg的:

main
Run Code Online (Sandbox Code Playgroud)

程序在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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

可能相关: 静态构造函数可以在非静态构造函数之后运行.这是编译器错误吗?

更新

在我的实际代码构造bar()函数中使用C++(非托管)初始化一些互操作代码.它需要在此库中的任何其他内容之前发生 - 是否有任何方法可以确保在没有放入init()触及库中所有静态(具有未外部引用的副作用)的函数的情况下?

未来搜索者的注意事项:我正在使用SWIG,这是他们在包装器生成代码中做出的假设. SWIGStringHelper是目前的罪犯,可能会有更多.

结论

更新到SWIG的2.0版本,它根据新版.NET的需要放入静态构造函数.

µBi*_*Bio 11

它可能会被优化,因为你不使用它.

它也不是编译器错误,它在语言规范中.

17.4.5.1静态字段初始化

类声明的静态字段变量初始值设定项对应于以它们出现在类声明中的文本顺序执行的赋值序列.如果类中存在静态构造函数(第17.11节),则在执行该静态构造函数之前立即执行静态字段初始值设定项.否则,静态字段初始化器 在第一次使用该类的静态字段之前的实现相关时间执行

由于您从不使用Program类的静态字段,因此无法保证静态初始化程序运行(尽管它可能......上面的'实现相关时间')

更新
您可以通过使程序具有静态构造函数来完成您想要的任务.

static Program (){} 或者可能通过访问另一个(可能是虚拟的)静态变量


Dir*_*mar 7

请注意,.NET 4.0中有一些关于静态初始化的更改.Jon Skeet撰写了一篇博客文章,其中包含一些示例:

在.NET 4.0中键入初始化更改

如果要进行精确初始化,则应使用静态构造函数(可能为空).

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)