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

时间:2009-10-16 12:28:40

标签: c# .net 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();
    }

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

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

更新:我现在直接从命令提示符处尝试,然后打印出“Caught pass in exception type”。因此看起来这仅限于在Visual Studio中运行。也许是Visual Studio托管过程的一个特点?

3 个答案:

答案 0 :(得分:33)

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

VS2k8控制台应用。以下内容:

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

导致“抓住一般异常”

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

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

导致“Caught在异常类型中传递” !!!


<强>更新

Heheh ......这是一个错误:https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=362422&wa=wsignin1.0

来源?这里。 Why does catch(TException) handling block behaviour differ under the debugger after installing Visual Studio 2008?

答案 1 :(得分: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);
    }
  }

答案 2 :(得分:2)

当给出T和Exception之间的选择时,似乎最具体的异常类型是异常,因此调用处理程序。

我刚试过这个(你不能用C#或VB做,但我编辑了IL),并改变了第二个catch子句来捕获Object Ex而不是Exception Ex,在那种情况下,第一个处理程序得到了击中。

修改

正如其他人所指出的,更多的是在调试器中运行它而不是特定类型