Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
单个C#类中的静态成员初始化顺序_C#_Static_Static Initialization - Fatal编程技术网

单个C#类中的静态成员初始化顺序

单个C#类中的静态成员初始化顺序,c#,static,static-initialization,C#,Static,Static Initialization,考虑以下带有两个静态成员变量的类片段: public static class Foo { static string A = GetA(B); static string B = "required for A"; ... 现在,我的理解是,A和B将在首次访问时初始化。然而,当我执行上面代码段的完全实现版本时,在B初始化之前访问了a,它导致null

考虑以下带有两个静态成员变量的类片段:

            public static class Foo
            {

                static string A = GetA(B);
                static string B = "required for A";
                ...
现在,我的理解是,
A
B
将在首次访问时初始化。然而,当我执行上面代码段的完全实现版本时,在
B
初始化之前访问了
a
,它导致
null
被传递到
GetA()
,而不是“所需的
”。为什么不开始初始化A,然后,当意识到初始化
A
需要
B
时,初始化
B
,然后返回以完成
A
的初始化


这方面的一般规则是什么?为什么会这样?我见过其他一些问题涉及到这一点(),但它们并没有准确地回答这个问题。主要讨论如何跨类而不是在单个类中工作(尽管Jon Skeet的答案补遗--“根据大众的需求,当我认为问题是关于类中静态变量的初始化顺序时,这里是我的原始答案:……”回答了这个问题,它被隐藏在更长的答案中)简言之,不要这样做

15.5.6.2静态字段初始化

类的静态字段变量初始值设定项对应于 按中的文本顺序执行的赋值序列 它们出现在类别声明中(§15.5.6.1)。在一段时间内 “文本顺序”的含义由 §15.5.6.1. 如果类中存在静态构造函数(§15.12), 静态字段初始值设定项的执行发生在 执行静态构造函数否则,静态字段 初始值设定项在执行之前在依赖于实现的时间执行 该类静态字段的首次使用

解决办法是:

  • 按顺序排列并使用静态构造函数
  • 或者只是在静态构造函数中初始化它们,从而使您能够控制初始化的顺序(给出上述信息)

就我个人而言,我建议在静态构造函数中初始化它们,这似乎使其更具体、更易懂,并且在重构过程中不太可能遇到碰撞

@Alexei Levenkov请参阅我的编辑,了解我认为这个问题应该与您链接的问题分开考虑的原因。基本上,虽然我的问题的答案隐藏在John Skeet对您链接的问题的回答中,但链接的问题主要涉及如何跨类而不是在单个类中工作。好的,我得到的是,一般情况下,事情是“按照它们出现的文本顺序执行的”。但是,如果一个静态字段的初始化取决于另一个静态字段的值,会发生什么情况呢?这是否会改变初始化顺序,即首先初始化所需的静态字段?我的例子似乎表明情况并非如此……总的来说,我仍然感到困惑。静态字段是按文本顺序初始化的,还是取决于先访问哪些字段?看看你的答案和Jon Skeet对Alexei Levenkov链接的问题的答案,我认为这就是答案:在类中,静态成员是按文本顺序初始化的。在不同的类中,它有点复杂,但简而言之“如果静态变量的初始值设定项表达式需要初始化另一个类型,那么在分配变量的值之前,另一个类型将被完全初始化-除非第二个类型已经被初始化(由于循环依赖)。”我相信“类型”是类的同义词。@Adam yes Jon的答案更精确,但前提是,只要你有空问题,就要在构造函数中初始化它们,在构造函数中你可以完全控制顺序。没有实现的复杂性,重构也不会影响逻辑。这也让我们更容易理解发生了什么以及为什么。无论如何,是的,你的结论似乎非常正确,祝你好运