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

时间:2010-08-26 22:50:39

标签: c# .net-4.0 clr

预期产量&输出我进入调试模式,并在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的需要放入静态构造函数。

2 个答案:

答案 0 :(得分:10)

它可能已经过优化,因为你没有使用它。

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

  

17.4.5.1 静态字段初始化

     

静态字段变量初始值设定项   类声明对应于a   分配顺序   以文字顺序执行   它们出现在类声明中。   如果是静态构造函数(第17.11节)   存在于类中,执行   发生静态字段初始化程序   在执行之前   静态构造函数。否则,   执行静态字段初始值设定项   在依赖于实现的时间   在第一次使用静电之前   该类的领域

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

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

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

答案 1 :(得分:7)

请注意,.NET 4.0中有一些关于静态初始化的更改。 Jon Skeet撰写了一篇博文,内容包括一些样本:

  

<强> Type initialization changes in .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();
        }
    }
}