C#初始化混乱 - 一个独立的静态类

时间:2014-03-04 18:23:00

标签: c# initialization

如果这是一个新手问题,我很抱歉,但我找不到任何类似于搜索S.O.的内容。我继承了一个小的C#程序来增强它,它主要是一个DLL。

我用一种伪代码表达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;
   }

当从DLL的调用者实例化CMain时,在调试器中,CGlobals中的静态变量在其他任何事情发生之前初始化为 first 。然后调用CMain的构造函数。

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

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

4 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

静态变量将在您调用之前初始化...但是有什么理由不能使用静态类吗?

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

这可以更好地表达您想要完成的任务。

答案 2 :(得分:1)

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

第一次访问类型成员时会发生静态初始化。因此,虽然CGlobals可能无法与CMain同时初始化,但会在第一次尝试访问其成员时对其成员进行初始化。

此行为有一个例外:在.NET 4.0及更高版本中运行“发布”程序集时,可以在运行时自行决定是否延迟静态字段初始值设定项。初始化值在您第一次尝试访问它们时仍然可用,但它们可能不会立即初始化,也不会按声明的顺序初始化。但是,仍然应该尊重依赖性。如果你正在处理标量值,并且初始化器没有副作用,那么这些都不会对你有所影响。

答案 3 :(得分:1)

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

访问权限可以是:

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