如何解决在Main之前调用的隐式静态构造函数
我有以下几段代码。
class Program
{
static void Main(string[] args)
{
Enterprise.Initialize("Awesome Company");
// Assertion failed when constructor of 'Reg' class is disabled.
Debug.Assert(Reg.Root == @"Software\Awesome Company");
}
}
public static class Enterprise
{
// Static Properties.
public static string Company
{
get;
private set;
}
// Static Methods.
public static void Initialize(string company)
{
Company = company;
}
}
public class Reg
{
public static string Root = $@"Software\{Enterprise.Company}";
// ctor.
static Reg()
{
// Assertion failed when this constructor is disabled.
}
}
执行后,断言通过。但是,在禁用Reg
类的构造函数时,断言失败。仔细观察,我发现Reg
类的隐式构造函数在Main()
之前被调用。如果明确定义了Reg
类的构造函数,则将在Main()
之后调用它。
为什么隐式和显式构造函数之间存在这种差异?
解决方法
这是链接的静态类初始化的怪癖。
15.5.6.2静态字段初始化
类的静态字段变量初始值设定项对应于 按文本顺序执行的作业序列 它们出现在类声明中(第15.5.5.6.1节)。在一个 局部类,“文本顺序”的含义由 §15.5.6.1。如果类中存在静态构造函数(第15.12节), 静态字段初始化程序的执行紧接在 执行该静态构造函数。 否则,静态字段 初始化程序在与实现相关的时间执行,然后 该类的静态字段的首次使用。
请特别注意最后一部分,这是您的问题,如果您没有静态构造函数,则无法控制何时初始化字段。在您的测试用例中,它们在调用Enterprise.Initialize
简而言之,您不应该依赖这些规则,它很容易出错,并且很可能引起奇怪的问题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。