考虑到以下流畅的 API 调用:
Foo()
.Bar1(() => { ... })
.Bar2(() => { ... })
.Bar3();
我想确定代码文件以及 Bar1、Bar2 和 Bar3 行的行号(稍后向下(呃...向上)它们的调用堆栈...
)情况 1: ...在 Bar1/Bar2/Bar3 扩展方法内。
我当前的解决方案:我立即在这些方法中创建堆栈跟踪并查找信息。
Unresolved 问题:行信息属于 Foo()
行,而不是 Bar#(...)
行 :(
情况 2: ...稍后,在代码中完全其他的地方,以防给定委托(delegate)在执行时抛出异常。
我当前的解决方案:我检查异常的堆栈跟踪并找到正确的行:)
特殊情况 3: Bar3 在方法内部定义了委托(delegate),当此类委托(delegate)抛出异常时,我现在仍然想要 .Bar3()
行。
我当前的解决方案:还不知道,委托(delegate)是在其他地方创建的,我无法使用与情况 2 相同的方法。但是,我唯一的机会是来自情况 1 的信息,该信息不完全正确(行号错误)。
问:您知道如何确定这三种情况下正确的代码文件和行号吗?
注意:性能并不那么重要,因为这是测试框架的一部分。
最佳答案
.NET 4.5 包括 Caller Information Attributes这是一种更简洁的方法:
using System.Runtime.CompilerServices;
...
public Foo Bar1(
Action,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
...
}
这里的最大好处是您不必在运行时执行任何操作。这些参数是在编译时提供的,因此这不会影响方法的性能。不幸的是,没有什么可以阻止用户代码绕过这个,例如:
Foo().Bar1(() => { ... }, "not a real method", "not a real file", -123);
关于c# - StackTrace,流畅调用的线路信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17802855/