首先,我讀過this answer,不,它只是說它是如何實現的,現在,但並不能解釋爲什麼。爲什麼「DisplayClass」和調用方法名稱在堆棧跟蹤中以這種方式排序?
這裏的一個示例程序(同here):
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()
方法,並有「魔術課」c__DisplayClass2
專門爲implMain()
局部變量製作。所以對我來說,它看起來像上線應該是這樣的:
at ConsoleApplication1.Program.implMain.c__DisplayClass2.b__0()
(也許有一些額外的符號,以防止可能發生的衝突),但我希望我的想法是明確的 - 這樣它看起來像c__DisplayClass2
專門製作以促進implMain()
的運作。
當前實現顯示方法名稱(implMain
)後,本地變量捕獲類名稱(c__DisplayClass2
),而不是反之亦然嗎?
[此鏈接](http://stackoverflow.com/a/3885161/335858)可能是一個有趣的閱讀。 – dasblinkenlight 2013-05-08 10:15:32