在C++中,我可以获取函数的地址并覆盖前几个字节以进行跳转到我的函数,然后执行一些操作,恢复原始字节并调用原始函数。
在C#中我能否做类似的事情?
.NET Profiler API是截取运行时方法最接近“微软认可”的方式。正如已经提到的,这在实现上有些困难,我不知道是否有一个纯粹使用托管代码就能轻松实现的库。
在几个月前研究选项时,我偶然发现了CLR Method Injection,这是一篇带有源代码的文章,解释了如何在运行时拦截方法。我考虑过自己使用它,甚至已经让示例项目工作,但最终得出结论,我需要的不仅仅是方法拦截,还需要另一个解决方案。然而,这种方法直接回答了你的问题。
最后,我所做的是开发Afterthought作为PostSharp的开源替代品,它作为编译后步骤运行,并允许您修改现有方法以调用其他代码,或者完全替换方法实现。我现在正在开发新的流畅语法,以下是一个示例,以帮助您了解这种AOP方法如何满足您的需求:
Methods
.Named("Sum")
.WithParams<int[]>()
.Before((T instance, ref int[] values)
=> { var s = new Stopwatch(); s.Start(); return s; })
.After((instance, stopwatch, values)
=> instance.Result = (int)stopwatch.ElapsedMilliseconds);
Sum
的方法时,我会在方法之前和之后添加代码来测量执行时间。运行Afterthought来处理原始编译类后,生成的Sum方法将在方法体之前和之后调用这些lambda表达式(C#编译器只是将它们转换为静态方法)。我也可以轻松地调用Implement
并替换整个方法实现。