更改私有只读属性的求值顺序

本文关键字:顺序 只读属性 | 更新日期: 2023-09-27 18:20:31

如果您有以下内容:

 public class MyClass {
      private static readonly MyObject obj = 
              new MyObject { parent = listObject[0] };
      private static readonly List<MyObject> listObject = 
              new List<MyObject> { new MyObject() };
 }

初始化MyClass时,它将引发运行时错误,因为当它尝试初始化obj时,listObject为null。

编辑:是否有方法明确指定每个只读对象何时初始化(例如通过属性),以便listObject在obj之前初始化(而不是重构或重新排序代码)?我意识到订单决定了每个项目何时执行,但让订单决定似乎很脆弱。

我为代码过于简单提前道歉。

更改私有只读属性的求值顺序

public class MyClass {
    private static readonly MyObject obj;
    private static readonly List<MyObject> listObject;
    static MyClass()
    {
        listObject = new List<MyObject> { new MyObject() };
        obj = new MyObject { parent = listObject[0] };
    }
}

如果将初始化带入构造函数,则可以重新排列字段的初始化顺序。

成员变量和静态变量的初始化保证按照它们在文件中出现的顺序进行。因此,可以通过首先初始化列表来避免编译时错误:

static readonly List<MyObject> listObject = new List<MyObject> { new MyObject() };
static readonly MyObject obj = new MyObject { parent = listObject[0] };

我会选择在构造函数中初始化你的字段。依赖于要按照字段的声明顺序进行初始化是相当脆弱的。如果有人改变了领域的顺序来满足他们的审美需求呢?繁荣

您需要一个静态构造函数!!

public class MyClass {
    private static readonly MyObject obj;
    private static readonly List<MyObject> listObject;
    static MyClass()
    {
        listObject = new List<MyObject> { new MyObject() };
        obj = new MyObject { parent = listObject[0] };
    }
}

"在创建第一个实例或引用任何静态成员之前,会自动调用静态构造函数来初始化类。"

静态字段的顺序很重要。它们是从上到下初始化的,您可以重新排列它们来解决问题。

 public class MyClass { 
     private static readonly List<MyObject> listObject = 
              new List<MyObject> { new MyObject() };
     private static readonly MyObject obj = 
              new MyObject { parent = listObject[0] };
 }

但这可能会带来意想不到的问题,例如,当代码格式化程序按字母顺序对字段定义进行排序时。

字段初始化程序是按代码顺序显式执行的,即自上而下。请注意,如果在单独的文件中使用分部类,这仍然是未定义的。

但是:如果顺序很重要,那么您应该将代码移动到构造函数(在这种情况下是静态构造函数)中。重新排序相互依赖的字段初始化程序只是在维护过程中遇到麻烦。