【问题标题】:Changing order that private readonly properties are evaluated更改评估私有只读属性的顺序
【发布时间】:2013-06-28 22:18:37
【问题描述】:

如果您有以下情况:

 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 为空。

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

对于过于简单的代码,我提前道歉。

【问题讨论】:

标签: c# c#-4.0


【解决方案1】:
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] };

我仍然会选择在构造函数中初始化您的字段。依赖于按照声明顺序初始化的字段是非常脆弱的。如果有人改变字段的顺序来满足他们的审美需求怎么办?繁荣。

【讨论】:

  • 这实际上不起作用,因为静态方法在非静态构造函数之前被调用。
  • 或者您可以将变量“listObject”提升为属性并延迟加载。
  • 我认为构造函数不会影响静态初始化器。
【解决方案2】:

你需要static constructor!!

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] };
    }
}

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

【讨论】:

  • 别担心,我没有。我确实从 OP 复制了。当你有一个实例构造函数而不是静态的时,我发布了这个。 SimpleClass() 构造函数(我已经将其更改为 MyClass)来自我从 MSDN 发布的链接。
【解决方案3】:

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

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

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

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      猜你喜欢
      • 2018-02-12
      • 2011-06-05
      • 1970-01-01
      • 1970-01-01
      • 2018-12-15
      • 2012-06-10
      • 2023-03-31
      • 1970-01-01
      • 2013-03-09
      相关资源
      最近更新 更多