当前位置:  开发笔记 > 编程语言 > 正文

C#中的静态构造函数/初始化程序的顺序

如何解决《C#中的静态构造函数/初始化程序的顺序》经验,为你挑选了2个好方法。

在使用C#应用程序时,我只是注意到在几个地方静态初始化程序彼此依赖,如下所示:

static private List a = new List() { 0 };
static private List b = new List() { a[0] };

没有做任何有用的特殊工作.这只是运气吗?C#有解决这个问题的规则吗?

编辑:( re:Panos)在一个文件中,词汇顺序似乎是王道?跨文件怎么样?

看起来我尝试了这样的周期性依赖:

static private List a = new List() { b[0] };
static private List b = new List() { a[0] };

并且该程序没有运行相同(测试套装全面失败,我没有看得更远).



1> Cowan..:

有关规则,请参阅C#规范的10.4节:

初始化类时,首先将该类中的所有静态字段初始化为其默认值,然后以文本顺序执行静态字段初始值设定项.同样,当创建类的实例时,首先将该实例中的所有实例字段初始化为其默认值,然后以文本顺序执行实例字段初始值设定项.具有可变初始值设定项的静态字段可以在其默认值状态下被观察到.然而,作为一种风格问题,强烈建议不要这样做.

换句话说,在您的示例中,'b'被初始化为其默认状态(null),因此在'a'的初始化程序中对它的引用是合法的,但会导致NullReferenceException.

这些规则与Java不同(请参阅 JLS for Java关于前向引用的规则的第8.3.2.3节,这些规则更具限制性).



2> Panos..:

它似乎取决于线的顺序.此代码有效:

static private List a = new List() { 1 };
static private List b = new List() { a[0] };

虽然这段代码不起作用(它抛出一个NullReferenceException)

static private List a = new List() { b[0] };
static private List b = new List() { 1 };

所以,显然没有关于周期性依赖的规则.然而,奇怪的是编译器没有抱怨......


编辑 - "跨文件"发生了什么?如果我们声明这两个类:

public class A {
    public static List a = new List() { B.b[0] };
}
public class B {
    public static List b = new List() { A.a[0] };
}

并尝试使用以下代码访问它们:

try { Console.WriteLine(B.b); } catch (Exception e) { Console.WriteLine(e.InnerException.Message.); }
try { Console.WriteLine(A.a); } catch (Exception e) { Console.WriteLine(e.InnerException.Message); }
try { Console.WriteLine(B.b); } catch (Exception e) { Console.WriteLine(e.InnerException.Message); }

我们得到这个输出:

The type initializer for 'A' threw an exception.
Object reference not set to an instance of an object.
The type initializer for 'A' threw an exception.

因此初始化B会导致静态构造函数A和lefts字段中的异常a具有默认值(null).既然anull,b也不能正确初始化.

如果我们没有周期依赖,一切正常.


编辑:为了防止你没有阅读评论,Jon Skeet提供了一个非常有趣的阅读:静态构造函数和类型初始值设定项之间的区别.


这里要小心静态变量初始化器和静态构造器之间的区别.基于静态构造函数的存在/不存在,何时发生类型初始化有不同的规则.请参见http://pobox.com/~skeet/csharp/beforefieldinit.html
推荐阅读
和谐啄木鸟
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有