【问题标题】:C# static field, instance constructorC# 静态字段,实例构造函数
【发布时间】:2014-09-16 06:05:30
【问题描述】:

我遇到了一个我想了解的 C# 行为。考虑这样一个类:

public class SomeSingleton
{
    public static SomeSingleton Default = new SomeSingleton();

    private static int field = 0;

    private SomeSingleton()
    {
        field = 1;
    }

    public int GetField()
    {
        return field;
    }
}

现在,让我们调用 GetField() 方法:

var field = SomeSingleton.Default.GetField();

我得到0 好像跳过了实例构造函数。为什么?

【问题讨论】:

    标签: c# .net constructor static


    【解决方案1】:

    只需在Default 之前交换field 声明的顺序。

    所以你的台词:

    public static SomeSingleton Default = new SomeSingleton();
    private static int field = 0;
    

    应该是:

    private static int field = 0;
    public static SomeSingleton Default = new SomeSingleton();
    

    原因是由于字段初始化顺序。首先在您的代码中初始化Default,它为field 分配1 的值。稍后在初始化中为该字段分配0。因此,您会看到 0 的最新值,而不是 1。

    见:10.4.5.1 Static field initialization

    类的静态字段变量初始化器对应于 在文本顺序中执行的分配序列 它们出现在类声明中。

    【讨论】:

    • 更好的是,完全取出 field 的初始化程序。首次创建对象时(对于静态字段,首次加载类型时),所有字段都预设为零(或 null)。
    【解决方案2】:

    这是因为static 变量的顺序。如果切换两个语句,输出变为1:

    private static int field = 0;
    
    public static SomeSingleton Default = new SomeSingleton();
    

    这是MSDN: Static field initialization 中记录的预期行为。

    见this .NET Fiddle。

    【讨论】:

    • +1 感谢 .NET Fiddle 的链接,出色的工具。
    【解决方案3】:

    切换静态变量的顺序。

    private static int field = 0;
    public static SomeSingleton Default = new SomeSingleton();
    

    在您的代码中,构造函数首先运行,它设置field,然后field 覆盖其值。

    【讨论】:

      猜你喜欢
      • 2011-04-19
      • 1970-01-01
      • 1970-01-01
      • 2013-03-05
      • 2011-05-08
      • 1970-01-01
      • 2012-04-15
      • 1970-01-01
      • 2015-08-06
      相关资源
      最近更新 更多