C#中的模块初始值设定项

Ein*_*son 23 c# clr clr-module-initializer

模块初始值设定项是CLR的一项功能,无法在C#或VB.NET中直接使用.它们是名为的全局静态方法.cctor,保证在执行程序集中的任何其他代码(类型初始化程序,静态构造函数)之前运行.我最近想在一个项目中使用它并使用Mono.Cecil 将我自己的解决方案(控制台程序/ msbuild任务)一起攻击,但我想知道:

  1. 有没有办法欺骗C#编译器发射模块初始化器?任何属性(例如CompilerGenerated,SpecialName)或其他可以使用的技巧?

  2. C#/ VB.NET是否会出于某种目的自己发出这些初始化器?从我所看到的它们被托管C++用于某些互操作目的,但我找不到任何引用它们用于其他目的.有任何想法吗?

Dav*_*oth 10

查看由Simon Cropp撰写的令人敬畏的开源IL-Weaver项目" fody " 的模块初始化程序插件:https://github.com/fody/moduleinit

它允许您指定一个方法,该方法将由fody转换为汇编初始值设定项:

public static class ModuleInitializer
{
    public static void Initialize()
    {
        //Init code
    }
}
Run Code Online (Sandbox Code Playgroud)

得到这个:

static <Module>()
{
    ModuleInitializer.Initialize();
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的建议.这实际上是基于我在问这个问题后写的自己的代码.Simon Cropp随后将其改编为他出色的Fody项目的插件. (8认同)

Max*_*erl 8

不,没有办法在C#中发出它们,因为C#将所有内容放在类/结构中,模块初始化器需要是全局的.

您将不得不使用不同的工具来编写它们,最好是IL-Assembler.

关于第二个问题,我不得不承认我不知道,但我从未见过任何由C#生成的,而且我经常使用ILDasm,所以我认为它不会发出它们.


Car*_*ujo 6

时隔十一年,这个终于被C#9的语言支持了

https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-9#support-for-code-generators

  • 我不太明白你在这里的推理。代码生成器是与模块初始化程序完全独立的功能,其工作方式完全不同。模块初始值设定项通过特定于该目的的属性来启用。是的,您可以使用生成器将初始化程序嵌入到其他人的模块中,但这是完全不同的事情。 (2认同)