在发布模式下编译可执行文件(启用代码优化)时,编译器可能会选择内联满足特定标准的函数以提高性能。
我的问题是:当内联函数体中抛出异常时,是否会保留堆栈跟踪信息而不管内联扩展如何?换句话说,它将显示原始函数作为错误源,还是显示调用函数?
这取决于异常是如何引发的。如果您使用throw语句,那么您没有问题,jitter 不会内联包含 throw 的方法。当您需要一个快速的属性设置器时需要注意的事情。
但是,如果异常是由正常执行引起的,例如 NullReferenceException 或 IndexOutOfRangeException 等,那么是的,如果是内联的,则不会在堆栈跟踪中看到该方法的名称。这可能有点令人困惑,但您通常可以从调用方法的源代码和异常类型中弄清楚。希望它相对较小。该[MethodImpl(MethodImplOptions.NoInlining)]
属性可用于抑制内联。当您发现它会有所帮助时,通常为时已晚;)
这不是一个确定的答案,但我试图装饰一个简单的方法,它只使用 .NET 4.5 中的属性来除以零,该[MethodImpl(MethodImplOptions.AggressiveInlining)]
属性提示 JIT (实际上执行内联)内联某个方法,当我运行程序在release模式下,异常是调用方法报的,不是除法的。另一方面,正如 Hans 所说,带有 throw 语句和复杂流逻辑的方法没有内联。MSDN 博客上的这篇文章(尽管从 2004 年开始)向您概述了 JIT 如何完成内联。