扔VS重新抛出:同样的结果?

Pra*_*eek 10 c# exception-handling throw rethrow

在网上引用了很多文档,尤其是关于SO的文档,例如:在C#中重新抛出异常的正确方法是什么? "扔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;
  }
   }
}
Run Code Online (Sandbox Code Playgroud)

给出以下结果:

$ /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()
Run Code Online (Sandbox Code Playgroud)

这与博客文章完全矛盾.

使用以下代码获得相同类型的结果: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#编程语言?

更新:此优化似乎符合:投掷VS重新抛出:相同的结果?(感谢0xA3)

在此先感谢您的帮助.

Luk*_*keH 4

我无法复制该问题 - 使用 .NET 3.5(32 位)给我带来了 Bart 文章中描述的相同结果。

我的猜测是 .NET 4 编译器/抖动(或者如果在 3.5 下也发生这种情况,则可能是 64 位编译器/抖动)正在将该方法BadGuy内联到调用方法中。尝试添加以下MethodImpl属性BadGuy,看看是否有任何区别:

[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
private static void BadGuy()
{
    //
    // Some nasty behavior.
    //
    throw new Exception();
}
Run Code Online (Sandbox Code Playgroud)