时间:2010-07-25 10:57:11

标签: c# cil

5 个答案:

答案 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的优势而没有命中。

完整的源代码位于http://www.glennslayden.com/code/c-sharp/inline-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指令。