In C#, you can apply the [MethodImpl(MethodImplOptions.AggressiveInlining)]
attribute to any method to ensure that the JIT inlines calls to it in most places (as opposed to relying on heuristics recognising short methods). When it should be applied is controversial, but modern .NET generally does well enough on its own that the attribute isn't necessary. (Sadly I'm stuck working with .NET Framework.)
I'm curious whether it has any effect on finalizers (destructors, ~TypeName() {}
), seeing as they can take any attribute applicable to AttributeTargets.Method
, including [MethodImpl]
. From the docs, I gather that the GC calls each Finalize
implementation going up the class inheritance chain—would these calls be eligible for inlining? Not that I expect it would make a noticeable difference if so.
No.
This is mostly due to how the C# compiler ensures that the whole inheritance chain is walked for all the Finalizer
methods. The compiler generates a try-finally
block:
try
{
// Derived Finalizer code goes in here
}
finally
{
base.Finalize();
}
And methods containing try-(catch)-finally
blocks are not eligible for inlining according to this (old) source cited in this so question. The answer provides a good explanation as to why this makes sense.
This is still the case for .NET 8 - sharplab link