catch中是否支持通用异常?

Mar*_*der 12 c# generics try-catch visual-studio-2008

上面提到的另一个问题+答案在SO上没有包含正确的答案,适用于此处!

我有一个用于单元测试的方法.此方法的目的是确保一段代码(由委托引用)将抛出特定异常.如果抛出该异常,则单元测试成功.如果没有抛出异常或抛出其他类型异常,则单元测试将失败.

/// <summary>
/// Checks to make sure that the action throws a exception of type TException.
/// </summary>
/// <typeparam name="TException">The type of exception expected.</typeparam>
/// <param name="action">The code to execute which is expected to generate the exception.</param>
public static void Throws<TException>(Action action) 
    where TException : Exception
{
    try
    {
        action();
    }
    catch (TException)
    {
        return;
    }
    catch (Exception ex)
    {
        Assert.Fail("Wrong exception was thrown. Exception of type " + ex.GetType() + " was thrown, exception of type " + typeof(TException) + " was expected.");
    }
    Assert.Fail("No exception was thrown. Exception of type " + typeof(TException) + " was expected.");
}
Run Code Online (Sandbox Code Playgroud)

下一个调用应该成功,但它失败了:

int result = 0;
Throws<DivideByZeroException>(() => result = result / result);
Run Code Online (Sandbox Code Playgroud)

TException抛出预期的类型异常时,它总是被第二个catch捕获,而不是第一个catch捕获.为什么是这样?

当然,我可以使用带有一个catch的workarround并测试是否ex类型TException.我只是想知道/理解为什么这个代码编译但是简单(从不?)有效.

编辑

根据要求提供"工作"演示:

using System;

namespace GenericExceptionDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = 0;
            Catch<DivideByZeroException>(() => n = n / n);
        }

        static public void Catch<TException>(Action action)
            where TException: Exception
        {
            try
            {
                action();
                Console.WriteLine("No exception thrown. !!!Fail!!!");
            }
            catch (TException)
            {
                Console.WriteLine("Expected exception thrown. PASS!");
            }
            catch(Exception ex)
            {
                Console.WriteLine("An unexpected exception of type " + ex.GetType() + " thrown. !!!FAIL!!!");
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Chr*_*cer 2

您不是第一个遇到此问题的人。这个问题 很相似。如果您深入研究答案和链接,就会发现这是 CLR 中的一个错误。

编辑:作为后续,我从 VS2010 运行 Martin 的示例并得到以下结果:

  • 针对 .NET 4,通过
  • 针对 .NET 3.5,失败
  • 以 RELEASE 模式瞄准 .NET 3.5,PASS

遗憾的是,所有指向 Microsoft Bug 报告的 SO 链接现在都已失效,我无法找到任何其他链接。