如何运行静态构造函数?

maf*_*afu 41 .net c# static-constructor

我想在不创建实例的情况下执行类的静态构造函数(即我想"加载"类).我怎么做?

加分问题:.NET 4和旧版本之间有什么区别吗?

编辑:

  • 这个班不是静态的.
  • 我想在创建实例之前运行它,因为它需要一段时间才能运行,我想在第一次访问时避免这种延迟.
  • 静态ctor初始化private static readonly字段因此不能在方法中运行.

Gar*_*ott 107

其他答案非常好,但是如果你需要强制一个类构造函数在没有引用类型(即反射)的情况下运行,你可以使用:

Type type = ...;
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle);
Run Code Online (Sandbox Code Playgroud)

  • 是的,它运行静态ctor.它也是安全的,CLR只会让静态ctor执行一次. (4认同)
  • 事实上,这个方法是为编译器作者明确提供的,以确保确定性初始化:http://blogs.msdn.com/cbrumme/archive/2003/04/15/51348.aspx (2认同)
  • @tomosius是的,OP已正确标记了此解决方案。现有的[ECMA-335](https://en.wikipedia.org/wiki/Common_Language_Infrastructure)设计在本质上是“必需的”,因为为仅由静态构造函数构成的依赖关系图(可能是循环的)找到了可行的拓扑分类(“ .NET中的“类型初始值设定项”充其量是昂贵的,最坏的情况则证明是不可能的。由于该图与.NET中的正确类型层次结构完全脱节,因此模糊不清,因此有理由认为整个企业“不值得”。 (2认同)

Fáb*_*sta 17

只需引用一个静态字段即可.这将强制您的静态初始化代码运行.例如:

public class MyClass
{
    private static readonly int someStaticField;

    static MyClass() => someStaticField = 1;

    // any no-op method call accepting your object will do fine
    public static void TouchMe() => GC.KeepAlive(someStaticField);
}
Run Code Online (Sandbox Code Playgroud)

用法:

// initialize statics
MyClass.TouchMe();
Run Code Online (Sandbox Code Playgroud)


zum*_*ard 8

您也可以这样做:

type.TypeInitializer.Invoke(null, null);
Run Code Online (Sandbox Code Playgroud)

  • 请注意,“TypeInitializer.Invoke”将允许多次调用静态构造函数,而“RuntimeHelpers.RunClassConstructor”则阻止这种情况。 (3认同)

csa*_*uve 6

发生以下任一情况时,将调用cctor(静态构造函数);

  1. 您创建该类的实例
  2. 可以访问任何静态成员
  3. 在此之前的任何时间(如果BeforeFieldInit已设置)

如果要显式调用cctor,并假设您有其他静态成员,则只需调用/访问它们即可。

如果您在cctor中没有做任何非常有趣的事情,编译器可能会决定对其进行标记BeforeFieldInit,这将允许CLR选择尽早执行cctor的选项。此处对此进行了详细说明:http : //blogs.msdn.com/davidnotario/archive/2005/02/08/369593.aspx