在创建实例之前,我可以确保静态构造函数已经完成吗? [英] Can I make sure a static constructor has finished before I create an instance?

查看:22
本文介绍了在创建实例之前,我可以确保静态构造函数已经完成吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的类有一个在构造函数中使用的静态字段初始值设定项:

My class has a static field initializer which is used in the constructor:

class Foo {
  private static List<string> list = new List<string>()
  private static object listLock = new Object();

  public Foo(string s) {
    lock(listLock)
      list.Add(s);
  }
}

我的问题是,它偶尔会发生,在静态初始值设定项完成之前在构造函数中访问列表,导致访问 list 时出现 NullReferenceException.根据这个问题,只能保证静态初始化在可以创建实例,但不能创建完成.

My problem is, that it occasionally occurs, that the list is accessed in the constructor before the static initializer has finished, causing a NullReferenceException when accessing list. According to this question, it is only guaranteed that static initialization is started before an instance can be created, but not that it is finished.

有什么方法可以确保仅在静态构造函数完成后才调用构造函数(除了像 while(list == null){} 这样的丑陋黑客)?

Is there some way to ensure that the constructor is only called after the static one has finished (apart from ugly hacks like while(list == null){})?

推荐答案

这里有一个很好的链接,了解之前的细微差别-field-init,但确实:在此处添加显式静态构造函数应该强制运行时的手.请注意,while (list == null) {} 将不起作用,因为这强制运行时的手 - 你应该永远无法观察运行时告诉你的谎言,基本上.

Here's a good link on the nuances of before-field-init, but indeed: adding an explicit static constructor should force the runtime's hand here. Note that the while (list == null) {} will not work, because that also forces the runtime's hand - you should never be able to observe the lies that the runtime tells you, basically.

在显示的示例中,没关系.您永远不会看到 listLocklistnull.如果您真的要求它们在构造函数之前运行:

In the example shown, it won't matter. You will never see a null for listLock or list. If you really really demand that they run before constructors:

private static List<string> list;
private static object listLock;
static Foo() {
    list = new List<string>();
    listLock = new object();
}

但请注意,这并不是真正必要的,并且可能会对您的代码产生负面影响,尤其是在 .NET Core 3 中的新 JIT 可以额外处理 static readonly 字段的情况下voodoo 如果它们被整齐地初始化(我知道如果它们是没有显式静态构造函数的内联字段初始化器,它可以做到这一点;我不知道> 如果它们是由显式静态构造函数分配的,则它可以执行此操作).

But note that this is not really necessary and may negatively impact your code, especially with the new JIT in .NET Core 3 that can treat static readonly fields with extra voodoo if they are initialized neatly (I know it can do this if they are inline field initializers without an explicit static constructor; I don't know if it can do this if they are assigned by an explicit static constructor).

这篇关于在创建实例之前,我可以确保静态构造函数已经完成吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆