参考网上的大量文档,特别是在SO上,例如:
What is the proper way to re-throw an exception in C#?
“扔e”之间应该有区别和“扔”.
“扔e”之间应该有区别和“扔”.
但是,从:http://bartdesmet.net/blogs/bart/archive/2006/03/12/3815.aspx,
这段代码:
using System; class Ex { public static void Main() { // // First test rethrowing the caught exception variable. // Console.WriteLine("First test"); try { ThrowWithVariable(); } catch (Exception ex) { Console.WriteLine(ex.StackTrace); } // // Second test performing a blind rethrow. // Console.WriteLine("Second test"); try { ThrowWithoutVariable(); } catch (Exception ex) { Console.WriteLine(ex.StackTrace); } } private static void BadGuy() { // // Some nasty behavior. // throw new Exception(); } private static void ThrowWithVariable() { try { BadGuy(); } catch (Exception ex) { throw ex; } } private static void ThrowWithoutVariable() { try { BadGuy(); } catch { throw; } } }
给出以下结果:
$/cygdrive/c/Windows/Microsoft.NET/Framework/v4.0.30319/csc.exe Test.cs Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.1 Copyright (C) Microsoft Corporation. All rights reserved. $./Test.exe First test at Ex.ThrowWithVariable() at Ex.Main() Second test at Ex.ThrowWithoutVariable() at Ex.Main()
使用代码从http://crazorsharp.blogspot.com/2009/08/rethrowing-exception-without-resetting.html获得同样的结果
原来的问题:我做错了什么?
更新:与.Net 3.5 / csc.exe 3.5.30729.4926相同的结果
SUMUP:所有的答案都很棒,再次感谢.
所以原因是由于64位JITter有效地内联.
我只能选择一个答案,这就是为什么我选择了LukeH的答案:
他猜测了内联问题,其实可能与我的64位架构有关,
>他提供了NoInlining旗帜,这是避免这种行为的最简单的方法.
然而,这个问题现在又提出了另一个问题:这种行为是否符合所有.Net规范:CLR和C#编程语言?
更新:这个优化似乎符合:Throw VS rethrow : same result?(感谢0xA3)
在此先感谢您的帮助.
解决方法
我无法复制问题 – 使用.NET 3.5(32位)给出了与Bart文章中描述的相同的结果.
我的猜测是,.NET 4编译器/抖动 – 或者也许是64位编译器/抖动,如果这也发生在3.5以下 – 正在将BadGuy方法嵌入到调用方法中.尝试将以下MethodImpl
属性添加到BadGuy中,看看是否有所区别:
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] private static void BadGuy() { // // Some nasty behavior. // throw new Exception(); }