为什么是&;displayclass &;在堆栈跟踪中按此顺序调用方法名
本文关键字:顺序调用 方法 堆栈 displayclass 为什么 跟踪 | 更新日期: 2023-09-27 18:12:41
首先,我读了这个答案,没有,它只说它现在是如何实现的,但没有解释为什么。
下面是一个示例程序(与这里相同):
class Program
{
static void Main()
{
try {
implMain();
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
static void implMain()
{
for (int i = 0; i < 10; i++) {
invoke(() => {
Console.WriteLine(i);
throw new InvalidOperationException();
});
}
}
static void invoke(Action what)
{
what();
}
}
输出以下调用堆栈:
System.InvalidOperationException
at ConsoleApplication1.Program.<>c__DisplayClass2.<implMain>b__0()
at ConsoleApplication1.Program.invoke(Action what)
at ConsoleApplication1.Program.implMain()
at ConsoleApplication1.Program.Main()
注意这两行:
at ConsoleApplication1.Program.<>c__DisplayClass2.<implMain>b__0()
at ConsoleApplication1.Program.invoke(Action what)
下一条(带invoke()
)表示存在一个命名空间ConsoleApplication1
,其中包含Program
类,并且有成员invoke()
。这里从左到右对应于从外到内。
上面的(c__DisplayClass2
)再次表示有一个命名空间和一个类…
然后是c__DisplayClass2
,意思是"编译器为存储捕获的变量而选择的神奇名称",然后是<implMain>
,好像它是c__DisplayClass2
的参数。所以它读起来好像c__DisplayClass2
是Program
的一部分,implMain
是c__DisplayClass2
的一部分。
现在,正如我所看到的,它在逻辑上是相反的-有implMain()
方法和专门为implMain()
局部变量精心制作的"魔法类"c__DisplayClass2
。所以对我来说,上面的行应该是这样的:
at ConsoleApplication1.Program.implMain.c__DisplayClass2.b__0()
(也许用一些额外的符号来防止可能的冲突),但我希望我的想法是明确的-这样看起来c__DisplayClass2
是专门为促进implMain()
的功能而精心制作的。
当前实现在局部变量捕获类名(c__DisplayClass2
)之后显示方法名(implMain
)而不是相反,是否有任何原因?
<implMain>b__0()
只是方法的名称。
检查反汇编程序会告诉你这一点。<
和>
不表示泛型。
包含implMain
可能只是暗示了委托是在哪里创建的