如何将调用者成员名称与接口方法一起使用



我正在浏览大约 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可以做到这一点,但它不是一个免费工具,这里有一些替代方案。

最新更新