答案 0 :(得分:13)
我只是posted a utility,它允许整个C#函数体使用自定义属性自动替换为内联IL。与类似的实用程序一样,这可以通过ILDASM / ILASM往返进行,可以将其设置为构建后步骤。该工具还调整PDB,以便在调试器中的单个IL指令上保留单步执行和设置断点。它与其他一些往返IL内联器的不同之处在于它(仅)替代整个函数体,如下所示:
class MyClass
{
[ILFunc(@"
.locals init ([0] int32 i_arg)
ldc.i4.3
ret
")]
int MyFunc(int i_arg)
{
return 3;
}
};
对于高度性能关键的方法,我尝试使用DynamicMethod
来改进编译器生成的IL,但发现由于委托调用开销而导致的好处丢失了。假设没有您真正需要DynamicMethod
的运行时自定义,内联IL给出了手动调整的IL的优势而没有命中。
答案 1 :(得分:3)
答案 2 :(得分:2)
答案 3 :(得分:2)
答案 4 :(得分:2)
我将自己的工具添加到此处已经提供的解决方案列表中:InlineIL.Fody。
这使用Fody程序集编织工具在构建时修改程序集。这意味着您要做的就是安装NuGet软件包,向您的项目中添加配置文件,然后就可以完成。
然后为您提供了一个简单且类型安全的API,以发出IL指令,您可以将其与C#代码混合使用。我相信以这种方式编写IL比编写文本要容易得多,并且比ILGenerator
还方便,因为每个操作码都有自己的带有相关重载的方法。
下面是一个示例,其中包含using static InlineIL.IL.Emit;
:
public static void ZeroInit<T>(ref T value)
where T : struct
{
Ldarg(nameof(value));
Ldc_I4_0();
Sizeof(typeof(T));
Unaligned(1);
Initblk();
}
这显示了如何访问C#当前未公开的initblk
指令。