如果这是一个新手问题,我很抱歉,但我找不到任何类似于搜索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不是任何东西的成员;它只是坐在那里,独自一人,并被其他班级引用。
一切似乎都有效,但它让我感到紧张,因为我不知道它遵循的规则。有人可以解释一下与此相关的初始化顺序规则是什么,以及这有什么危险吗?
答案 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)
在对类的任何访问之前调用静态构造函数。任何访问非初始化类(具有静态构造函数)的尝试都将导致调用静态构造函数。
访问权限可以是: