2014-03-04 43 views
0

对不起,如果这是一个新手问题,但我找不到像搜索S.O.我已经继承了一个C#程序来增强,它主要是一个DLL。C#初始化困惑 - 一个独立的静态类

我在一种伪代码中表达了DLL来解释我的问题: 该DLL有4个类,3个“常规”类和第4类公共静态变量,这些变量被全局变量用作全局变量该DLL

public class CMain 
    { 
     public CMain() 
     { 
      CFoo Foo = new CFoo(); // CFoo's c'tor is called 
      CBar Bar = new CBar(); // CBar's c'tor is called 
      CGlobals.v1 = 123; 
     } 
    } 



    public class CFoo 
    { 
     ... 
    } 


    public class CBar 
    { 
     ... 
    } 


    public sealed class CGlobals 
    { 
     public static int v1 = 0; 
     public static int v2 = 0; 
    } 

当CMAIN从DLL的调用者实例化,在调试器中CGlobals的静态变量之前什么都发生初始化第一的休息。然后CMain的构造函数被调用。

当我查找C#初始化顺序时,我发现类的静态成员在类构造函数被调用之前被初始化,但是CGlobals不是任何成员;它只是坐在那里,独自一人,并从其他班级参考。

一切似乎都奏效,但它让我感到紧张,因为我不知道它遵循的规则。有人可以解释一下与此有关的初始化顺序规则是什么,以及这是否有什么危险?

+0

您确定在调用CMain的构造函数之前初始化了CGLobals静态字段吗?为什么要在初次使用CGlobals时初次使用它? –

回答

1

静态成员在实例成员之前被初始化是正确的。此外,实例字段初始值设定项在实例构造函数之前处理,静态字段初始值设定项在静态构造函数之前处理字段初始值设定项与层次结构中的构造函数按照相反的顺序运行,即大多数派生类的字段将在其基类字段之前初始化。

第一次访问类型的成员时发生静态初始化。因此,虽然CGlobals可能不会在CMain的同一时间初始化,但其成员将在您第一次尝试访问时初始化。

这种行为有个例外:在.NET 4.0及更高版本中运行“release”程序集时,运行时可能会推迟静态字段初始值设定项。第一次尝试访问它们时,初始化的值仍然可用,但它们可能不会全部立即初始化,或者按照它们声明的顺序进行初始化。尽管如此,依赖关系仍应该得到尊重。如果你正在处理标量值,并且初始值设定项没有产生副作用,那么这些都不会对你产生影响。

1

是的,静态变量在任何构造函数被调用之前被初始化。这些静态变量的值只能依赖于其他静态变量。

1

静态变量将被初始化,然后您可以调用它......但是有什么理由不能使用静态类吗?

public static class CGlobals 
{ 
    public static int v1=0; 
    public static int v2 = 0; 
} 

这是您试图完成的更好的表示。

+0

不知道。我没有写。我只是想确保C#保证执行单元中的所有静态变量都是首先初始化的,因为当我查找规范时,所有可能发现的地方都是静态成员首先被初始化。 – user316117

1

静态构造函数在任何对类的访问之前被调用。任何尝试访问非初始化类(具有静态构造函数)都会导致调用静态构造函数。

访问可以是:

  • 创建类的实例(对象)
  • 静态成员函数调用
  • 访问(读取或写入)的任何静态属性
  • 访问任何静态字段