none
静态构造方法执行错误(.net 4下用release编译) RRS feed

  • 问题

  • 要重现这个问题的代码很简单:
    class Program { private static ClassA a = new ClassA(); static void Main(string[] args) { Console.ReadLine(); } } class ClassA { static ClassA() { Console.WriteLine("A cctor"); } }

    只要访问ClassA,它的静态构造方法就会执行。
    所以程序一运行就应该输出“A cctor”。
    实际上如果target framework设为.net 2.0或者3.5的话输出结果都是“A cctor”。
    但是如果target framework是.net 4而且用release编译的话,编译出的程序集脱离IDE运行(在VS里运行结果还是对的)时则没有输出任何东西。

    太奇怪了,哪位知道怎么回事请帮忙,谢谢。
    2010年7月30日 16:53

答案

  • release 的时候会延迟加载  这是一种优化的执行方式  如果一个类型除了new以外  没有任何人防问它   他就会被延迟到第一次有人访问的时候加载

     

    你可以尝试下

    class Program
     {
      private static ClassA a = new ClassA();
    
      static void Main(string[] args)
      {
       ClassA.AValue=10;
       Console.ReadLine();
      }
     }
    
     class ClassA
     {
      static ClassA()
      {
       Console.WriteLine("A cctor");
      }
       static int AValue{get;set;}
     }
    

    成为 Microsoft V Dash了。。。 欢迎各位前辈同事在OCS加我
    • 已标记为答案 cuipengfei 2010年7月31日 8:15
    2010年7月31日 1:43

全部回复

  • release 的时候会延迟加载  这是一种优化的执行方式  如果一个类型除了new以外  没有任何人防问它   他就会被延迟到第一次有人访问的时候加载

     

    你可以尝试下

    class Program
     {
      private static ClassA a = new ClassA();
    
      static void Main(string[] args)
      {
       ClassA.AValue=10;
       Console.ReadLine();
      }
     }
    
     class ClassA
     {
      static ClassA()
      {
       Console.WriteLine("A cctor");
      }
       static int AValue{get;set;}
     }
    

    成为 Microsoft V Dash了。。。 欢迎各位前辈同事在OCS加我
    • 已标记为答案 cuipengfei 2010年7月31日 8:15
    2010年7月31日 1:43
  • 那这应该算作breaking change吧?

    如果我在.net 2.0下写了个类库,其中有一个类型的静态构造函数要执行一些全局的初始化操作, 而且外界对它的调用只是把它作为私有字段,然后new 一下就不再访问它了。现在如果把外界调用换到.net 4的话,初始化就执行不了了。

    虽然说这种设计不好,但是还是觉得这算是兼容性问题。

    2010年7月31日 3:08
  • 一个类型在被访问前不应当加载 这个是设计的原意

    如果你不希望某个声明被编译器和jit优化  请声明 为volatile   这个也是在兼容多版本开发中多次建议的

     


    成为 Microsoft V Dash了。。。 欢迎各位前辈同事在OCS加我
    2010年7月31日 3:59
  •    private static ClassA a = new ClassA();

     

    这句话可以吗?

    静态构造函数可以这么做吗?

    也没有这个必要把,静态构造,静态属性,在第一次访问类的时候应该是自动运行的吧。

    2010年7月31日 4:25
  • 谢谢,最近用了一个开源的库GDAL,其中的一个internal类型就是在用静态构造方法做初始化,而GDAL中唯一一个用到这个internal类型的地方就是把它声明为一个私有字段并且声明的时候就new了,结果我在.net4下调用时就出了问题,所以才有此一问。
    2010年7月31日 5:14