我正在浏览大约 700K 行代码。 大量的接口实现和 DI 使用。 我试图找出从哪里调用特定方法,因此我正在尝试使用[CallerMemberName]
.
我在谷歌等上看到的所有例子都是这样的:
public void TraceMessage(string message,
[System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
使用可选 parms 获取信息的位置。 我的问题是这种方法是接口实现的一部分。因此,当我更改方法签名时,编译器会对我大喊大叫。
任何关于如何使接口方法与[CallerMembername]
很好地配合的建议将不胜感激。
有一个类似的问题 - 发现我可以将 CallerMemberName 添加到接口方法中,如下所示。它确实更改了实现类的签名,但不会更改调用代码的签名 - 如果这有意义的话!
如果这是接口中方法的当前签名
void TraceMessage(string message);
更改如下
void TraceMessage(string message,
[System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
更新实现接口的类中的方法
public void TraceMessage(string message,
[System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
// Log the params
}
这仍然可以仅使用"消息"参数使用原始签名调用,并且其他参数仍将被拾取,因此无需重构所有调用代码
TraceMessage("Testing");
(为简洁起见添加(
using System.Runtime.CompilerServices;
您可以通过不同的方式获取呼叫者姓名,而无需更改任何签名,请尝试此解决方案
using System.Diagnostics;
// Get call stack
StackTrace stackTrace = new StackTrace();
// Get calling method name
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);
此解决方案比您尝试使用的编译时慢得多,但它的侵入性要小得多。
如果性能至关重要,并且您将 DI 与 IoC 容器一起使用,那么您可以检查它是否支持 Unity.Interception 或 Ninject.Extensions.Interception 等方面。您需要实现一个方面(拦截器(并将其注册到容器中,下面是缓存拦截器的示例。
如果不使用 IoC,您仍然可以使用 AOP 方法,并在您感兴趣的方法中添加某个方面。PostSharp可以做到这一点,但它不是一个免费工具,这里有一些替代方案。