强制类加载

12

在C#或者.NET IL中,有没有一种方法可以强制一个具有类型初始化程序(静态构造函数)的类加载自身,而不需要访问它的任何参数?

假设我已经拥有这个类:

public static class LogInitialization {
    static LogInitialization() {
        System.Console.WriteLine("Initialized");
    }
}

有没有办法让这一行打印出来?

请注意,这个类是静态的,所以我无法实例化它来强制初始化,而且它没有公共成员,所以我也无法访问它们来启动它。

2个回答

13
在CLI规范中搜寻时,我找到了一个有关方法的参考:RuntimeHelpers.RunClassConstructor

如果一种语言希望提供更严格的行为,例如类型初始化自动触发基类的初始化程序,并按自上而下的顺序执行,则可以通过以下两种方式之一来实现:

  • 在每个类构造函数中定义隐藏的静态字段和代码,该代码触及其基类和/或实现的接口的隐藏的静态字段
  • 调用System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(请参阅第IV部分)。

2
要使用它,请传入您的 Type 实例上的 TypeHandle 属性的结果。 - Sam

7
我通常在具有静态构造函数的类上创建一个虚拟(空)Init方法,以强制执行静态构造函数。例如:
public static void Initialize() 
{ 
  // this will force your static constructor to execute, obviously
}

说实话,你总是可以通过反射使用Type.TypeInitializer...http://msdn.microsoft.com/en-us/library/system.type.typeinitializer.aspx 编辑:我过去做过的另一件事是创建一个名为RequiresInitializationAttribute的属性,然后在AssemblyLoad上扫描具有此类属性的类型,并使用type.TypeInitializer来在加载包含程序集时强制执行静态构造函数。
我想真正的问题,像往常一样,是...你想要实现什么?

是的,我可以直接调用.cctor - 我只是不确定这是否会阻止CLR再次调用它。 - configurator
此外,调用静态类型的类型初始化程序会失败!“无法创建 A 的实例,因为它是一个抽象类。”我不明白为什么会出现这个消息,但这就是我得到的。 - configurator
至于我想要实现的目标,基本上是从一种具有严格规则的语言编译,这些规则涉及类应该何时加载 - 因此我希望在正确的时间加载它们。 - configurator
在 .net 4 中有一个问题,你可以看这里 https://msmvps.com/blogs/jon_skeet/archive/2010/01/26/type-initialization-changes-in-net-4-0.aspx - Yacov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接