private void Form1_Click(object sender, EventArgs e) { try { } catch { throw; } } private void Form1_Load(object sender, EventArgs e) { try { } catch (Exception) { throw; } } private void Form1_Enter(object sender, EventArgs e) { try { } catch (Exception ee) { throw; } } private void Form1_DoubleClick(object sender, EventArgs e) { try { } catch (Exception ee) { throw ee; } }
对应的IL代码(以下代码是release版本的IL代码):
.method private hidebysig instance void Form1_Click(object sender, class [mscorlib]System.EventArgs e) cil managed { // 代码大小 1 (0x1) .maxstack 8 IL_0000: ret } // end of method Form1::Form1_Click .method private hidebysig instance void Form1_Load(object sender, class [mscorlib]System.EventArgs e) cil managed { // 代码大小 1 (0x1) .maxstack 8 IL_0000: ret } // end of method Form1::Form1_Load .method private hidebysig instance void Form1_Enter(object sender, class [mscorlib]System.EventArgs e) cil managed { // 代码大小 1 (0x1) .maxstack 8 IL_0000: ret } // end of method Form1::Form1_Enter .method private hidebysig instance void Form1_DoubleClick(object sender, class [mscorlib]System.EventArgs e) cil managed { // 代码大小 1 (0x1) .maxstack 1 .locals init ([0] class [mscorlib]System.Exception ee) IL_0000: ret } // end of method Form1::Form1_DoubleClick
能够看到Form1_Click、Form1_Load、Form1_Enter中的try catch已被编译器优化掉了:
IL_0000: ret //即为 return 标记 返回值
只要Form1_DoubleClick中的try catch中对try catch进行了处置惩罚:
.locals init ([0] class [mscorlib]System.Exception ee) //定义 Exception 范例参数 ee (此时已把ee存入了Call Stack中)
即在Form1_DoubleClick中的try catch才会对机能发生影响。
==》能够看出一下三种try catch的写法关于release版本的代码来说是完整一样,也不会发生任何的机能斲丧:
try { } catch { throw; } try { } catch (Exception) { throw; } try { } catch (Exception ee) { throw; }
关于上面的结论人人能够写测试demo考证一下 (已测试,结果与剖析一致)。
那末关于debug形式下的IL代码是什么模样的呢?
.method private hidebysig instance void Form1_Click(object sender, class [mscorlib]System.EventArgs e) cil managed { // 代码大小 11 (0xb) .maxstack 1 IL_0000: nop .try { IL_0001: nop IL_0002: nop IL_0003: leave.s IL_0009 } // end .try catch [mscorlib]System.Object { IL_0005: pop IL_0006: nop IL_0007: rethrow } // end handler IL_0009: nop IL_000a: ret } // end of method Form1::Form1_Click .method private hidebysig instance void Form1_Load(object sender, class [mscorlib]System.EventArgs e) cil managed { // 代码大小 11 (0xb) .maxstack 1 IL_0000: nop .try { IL_0001: nop IL_0002: nop IL_0003: leave.s IL_0009 } // end .try catch [mscorlib]System.Exception { IL_0005: pop IL_0006: nop IL_0007: rethrow } // end handler IL_0009: nop IL_000a: ret } // end of method Form1::Form1_Load .method private hidebysig instance void Form1_Enter(object sender, class [mscorlib]System.EventArgs e) cil managed { // 代码大小 11 (0xb) .maxstack 1 .locals init ([0] class [mscorlib]System.Exception ee) IL_0000: nop .try { IL_0001: nop IL_0002: nop IL_0003: leave.s IL_0009 } // end .try catch [mscorlib]System.Exception { IL_0005: stloc.0 IL_0006: nop IL_0007: rethrow } // end handler IL_0009: nop IL_000a: ret } // end of method Form1::Form1_Enter .method private hidebysig instance void Form1_DoubleClick(object sender, class [mscorlib]System.EventArgs e) cil managed { // 代码大小 11 (0xb) .maxstack 1 .locals init ([0] class [mscorlib]System.Exception ee) IL_0000: nop .try { IL_0001: nop IL_0002: nop IL_0003: leave.s IL_0009 } // end .try catch [mscorlib]System.Exception { IL_0005: stloc.0 IL_0006: nop IL_0007: ldloc.0 IL_0008: throw } // end handler IL_0009: nop IL_000a: ret } // end of method Form1::Form1_DoubleClick
能够看出四种写法在debug形式下区分只是:rethrow与throw的区分。IL中rethrow与throw离别代表啥呢?
Throw:激发当前位于盘算客栈上的非常对象。
Rethrow:再次激发当前非常。
即当我们抛出一个非常时, CLR会从新设置一个非常起始点。 CLR只纪录近来一次非常抛出的位置。下面代码抛出一个非常,从而致使CLR从新设置该非常的起始点:
try { //一些处置惩罚 } catch (Exception e) { //一些处置惩罚 throw e; //CLR以为这里是非常的起始点 }
相反,假如我们抛出一个非常对象, CLR将不会从新设置其客栈的起始点,下面代码抛出一个非常,但不会致使CLR从新设置非常的起始点:
try { //一些处置惩罚 } catch (Exception e) { //一些处置惩罚 throw; //CLR不会从新设置非常的起始点 }
C#中运用throw和throw ex抛出非常,但两者是有区分的。
在C#中引荐运用throw;来抛出非常;throw ex;会将到现在为止的一切信息清空,以为你catch到的非常已被处置惩罚了,只不过处置惩罚过程当中又抛出新的非常,从而找不到真正的毛病源。
throw e从新抛出非常,并不是转发本来的非常,而会变动包含StackTrace在内的很多非常内部信息;关于挪用连很深状况,机能消耗超越设想。
以上就是C# 非常处置惩罚(Catch Throw)IL剖析的内容,更多相关内容请关注ki4网(www.ki4.cn)!