.NET(C#): 當等號遇到Exception

來源:互聯網
上載者:User

今天發現軟體中一個很奇怪Bug,究其原因是沒有正確理解“等號和異常”的問題,來看下面這段代碼:

static void Main(string[] args)

{

    int[] arr = new int[3];

    int i = 0;

 

    try

    {

        arr[i++] = doo();

    }

    catch { }

 

    Console.WriteLine(i);

}

 

static int doo()

{

    throw new Exception();

}

 

很簡單的邏輯,一個數組和一個int:i。然後給數組賦值,索引器中有i++操作。右邊調用的方法doo會拋出異常。

 

我起初是這樣錯誤地想:=是賦值操作,肯定是從右往左進行的,如果右面先出了異常,那麼很自然左面的代碼都不會運行了,此時會跳至catch快,所以上面的方法最終會輸出0。

 

正確的結果是輸出1。等號左面的代碼會全部啟動並執行。IL可以說明一切,下面是try{}中的IL:

.try

{

IL_000a: nop

//陣列變數進棧

IL_000b: ldloc.0

//i進棧

IL_000c: ldloc.1

//複製一個i到棧頂

IL_000d: dup

//數字1進棧

IL_000e: ldc.i4.1

//棧頂現在是i+1

IL_000f: add

//賦值給i變數,棧頂現在是變數i

IL_0010: stloc.1

//調用doo方法

IL_0011: call int32 Mgen.Test.Program::doo()

//設定數群組成員,索引值是i的值

IL_0016: stelem.i4

IL_0017: nop

IL_0018: leave.s IL_001f

} // end .try

 

那為什麼會出現這種誤解呢?原因是如果僅從“賦值”這個操作來說,我們可以想當然得認為就是把右面的資料設定給左面的資料,因此如果右面的資料出了異常,那麼左面是無法擷取到值的,所以會認為左面的邏輯也不會運行。但是從技術實現來看這個賦值操作,實際是先進行左面的操作的,因為賦值操作要Crowdsourced Security Testing道把值賦給誰,所以是左面的資料先進棧的,自然左面的操作會被執行,無論右面有沒有異常。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.