Is it possible to insert IL code to C# method?
I just posted a utility which allows entire C# function bodies to be automatically replaced with inline IL, using a custom attribute. Like similar utilities, this works via the ILDASM/ILASM round-trip which can be set up as a post-build step. The tool also adjusts the PDB in order to preserve single-stepping and setting breakpoints on individual IL instructions in the debugger. It's different from some of the other round-trip IL inliners in that it (only) substitutes for entire function bodies, like this:
class MyClass
{
[ILFunc(@"
.locals init ([0] int32 i_arg)
ldc.i4.3
ret
")]
int MyFunc(int i_arg)
{
return 3;
}
};
For highly performance-critical methods, I tried using DynamicMethod
to improve upon compiler-generated IL, but found that the benefit is lost due to the delegate-calling overhead. Inline IL gives the the beneft of hand-tuned IL without that hit, assuming there are no runtime customizations that you would truly need DynamicMethod
for.
The complete source code is located at http://www.glennslayden.com/code/c-sharp/inline-il
I'll add my own tool to the list of solutions already provided here: InlineIL.Fody.
This uses the Fody assembly weaving tool to modify the assembly at build time. Which means all you have to do is install a NuGet package, add a config file to your project and you're done.
You're then provided with a simple and type-safe API to emit IL instructions, which you can mix with C# code. I believe it's easier to write IL in this way than writing text, and it's also more convenient than ILGenerator
since each opcode gets its own method with relevant overloads only.
Here's an example, with 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();
}
This shows how to access the initblk
instruction which C# doesn't currently expose.
If inline IL (in the same spirit of inline assembly supported by C and C++ compilers) is what you're looking for, this can be achieved using post-compilation round-trip compiling.
Mike Stall has once written a tool for that, as far as I know it's fairly mature:
Other than that, you could use F# which supports Inline IL.
DynamicMethod is the lightweight way to accomplish this at runtime.
The Microsoft C# compiler doesn't support injection of IL at compile-time, but a code-weaving tool could do so as a post-compile step.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With