2013-05-08 14 views
0

首先,我讀過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的一部分,implMainc__DisplayClass2的一部分。

現在我看到它在邏輯上是相反的 - 有implMain()方法,並有「魔術課」c__DisplayClass2專門爲implMain()局部變量製作。所以對我來說,它看起來像上線應該是這樣的:

at ConsoleApplication1.Program.implMain.c__DisplayClass2.b__0() 

(也許有一些額外的符號,以防止可能發生的衝突),但我希望我的想法是明確的 - 這樣它看起來像c__DisplayClass2專門製作以促進implMain()的運作。

當前實現顯示方法名稱(implMain)後,本地變量捕獲類名稱(c__DisplayClass2),而不是反之亦然嗎?

+0

[此鏈接](http://stackoverflow.com/a/3885161/335858)可能是一個有趣的閱讀。 – dasblinkenlight 2013-05-08 10:15:32

回答

3

<implMain>b__0()只是方法的名稱。

在反彙編器中檢查會告訴你這個。 <>並不意味着泛型。

包含implMain可能只是提示創建代表的位置。

相關問題