为什么我不能在C#中捕获一般的异常?

Ein*_*son 40 .net c# generics exception-handling

我正在对代码进行一些单元测试,这可能会根据输入引发许多异常.所以我尝试了类似下面的代码:(简化示例)

    static void Main(string[] args)
    {
        RunTest<ArgumentException>();
    }

    static void RunTest<T>() where T : Exception, new()
    {
        try
        {
            throw new T();
            //throw new ArgumentException(); <-- Doesn't work either

        }
        catch (T tex)
        {
            Console.WriteLine("Caught passed in exception type");
        }
        catch (Exception ex)
        {
            Console.WriteLine("Caught general exception");
        }
        Console.Read();
    }
Run Code Online (Sandbox Code Playgroud)

但是这将始终打印出"抓住一般异常",catch(T tex)处理程序永远不会工作.无论我抛出T()还是显式抛出ArgumentException()都没关系.任何想法为什么会这样?实际上我有点惊讶我甚至能够在catch子句中使用T,但是因为那可能不应该这样做吗?或者至少给出一个编译器警告/错误,说明这个处理程序永远不会工作?

我的环境是Visual Studio 2008,3.5是目标框架.

更新:我现在直接从命令提示符尝试它,然后打印出"Caught传递异常类型".因此看起来这仅限于在Visual Studio中运行.也许Visual Studio托管过程的特殊性?

小智 34

这里奇怪的行为......

VS2k8控制台应用程序.下列:

try
{
    throw new T();
}
catch (T tex)
{
    Console.WriteLine("Caught passed in exception type");
}
catch (Exception ex)
{
    Console.WriteLine("Caught general exception");
}
Run Code Online (Sandbox Code Playgroud)

导致"抓到一般例外".

但是,从catch语句中删除(无用的)变量:

try
{
    throw new T();
}
catch (T)
{
    Console.WriteLine("Caught passed in exception type");
}
catch (Exception)
{
    Console.WriteLine("Caught general exception");
}
Run Code Online (Sandbox Code Playgroud)

导致"抓住异常类型传递" !!!


更新:

Heheh ......它是一个bug:https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx ?FeedbackID = 362422&wa = newsign1.0

资源?这里. 为什么安装Visual Studio 2008后,调试器下的catch(TException)处理块行为会有所不同?


Gui*_*ume 8

无需Debug即可运行

http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/0b0e5bc9-fab2-45b1-863b-40abae370475

丑陋的解决方法(你可以添加#if DEBUG):

  try
  {
    throw new T();
  }
  catch (Exception dbgEx)
  {
    T ex = dbgEx as T;
    if (ex != null)
    {
      Console.WriteLine(ex.Message);
    }
  }
Run Code Online (Sandbox Code Playgroud)