【问题标题】:Static field initialization order with partial classes部分类的静态字段初始化顺序
【发布时间】:2015-05-19 03:48:32
【问题描述】:

有没有办法强制部分类中的静态字段初始化顺序?假设在 HelloWorld1.cs 我有:

partial class HelloWorld
{
  static readonly string[] a = new[] { "Hello World" };
}

我在 HelloWorld2.cs 的其他地方有:

partial class HelloWorld
{
  static readonly string b = a[0];
}

如果 a 在 b 之前初始化,这很好,但如果 b 在 a 之前初始化,那么它会抛出 an。健康的方法可能是使用静态构造函数,但我很好奇当字段类位于同一个部分类的不同文件中时,是否有办法强制或预测初始化顺序。

【问题讨论】:

  • 您的用例是什么?在您给出的示例中, b 将在使用时从 a[] 返回预期值。所以,我不清楚你为什么关心......
  • 您在问题中拥有正确的答案。您应该使用静态构造函数。
  • @SilasReinagel,情况并非总是如此。如果 b 在 a 之前初始化,则该类将在静态初始化时抛出错误。在同一个文件中,排序是文本的,但是在同一个部分类的不同文件之间呢?
  • @AltonXL 代码将变得异常脆弱、可读性差、更难维护,即使有 已定义的顺序。你最好假设没有明确定义的顺序,不管是否存在。

标签: c# .net


【解决方案1】:

来自MSDN Documentation

类的静态字段变量初始化器对应于 以文本顺序执行的任务序列 它们出现在类声明中。如果是静态构造函数 (10.11节)存在于类中,执行静态字段 初始化器在执行该静态之前立即发生 构造函数。 否则,静态字段初始化器将在 在第一次使用静态之前的依赖于实现的时间 该类的字段。

【讨论】:

  • 同一部分类的所有字段都在同一个文件中时,文本顺序是可预测的。我很好奇什么时候在不同的文件中。那么是.cs文件名的文本顺序吗?
  • @AltonXL 这种情况下的顺序是特定于实现的,在规范中没有定义。即使您可以弄清楚它在此版本的 .NET CLR 中执行的顺序,Windows 更新也可能通过更改其处理顺序来破坏您的程序。
  • @ScottChamberlain,感谢您根据初始化顺序解释应该避免的原因,但我仍然想知道初始化顺序是否可预测。
  • @AltonXL 单看申报现场是无法预料的。
  • 谢谢@SilasReinagel。
【解决方案2】:

当字段存在于同一个文件中时,文本顺序定义了它们初始化的执行:

10.5.5.1 变量初始化器 - 静态字段初始化

类的静态字段变量初始化器对应于一系列赋值,它们按照它们在类声明中出现的文本顺序执行。如果类中存在静态构造函数(第 10.12 节),则在执行该静态构造函数之前立即执行静态字段初始值设定项。否则,静态字段初始值设定项会在第一次使用该类的静态字段之前的依赖于实现的时间执行。

但是,对于分部类的不同文件中声明的字段,顺序是不确定的:

10.2.6 部分类型 - 成员

类型中成员的顺序对于 C# 代码来说很少重要,但在与其他语言和环境交互时可能很重要。 在这些情况下,在多个部分中声明的类型中成员的顺序是未定义的

来自C# language specification

【讨论】:

    猜你喜欢
    • 2010-12-02
    • 1970-01-01
    • 1970-01-01
    • 2017-05-31
    • 2018-12-19
    • 1970-01-01
    • 2014-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多