catch中支持的泛型异常

本文关键字:泛型 异常 支持 catch | 更新日期: 2023-09-27 18:16:55

上面提到的关于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.");
}

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

int result = 0;
Throws<DivideByZeroException>(() => result = result / result);

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

当然,我可以使用一个捕获和测试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!!!");
            }
        }
    }
}

catch中支持的泛型异常

您不是第一个遇到这个问题的人。这个问题很相似。如果你仔细研究答案和链接,就会发现这是CLR中的一个bug。

编辑:接下来,我在VS2010中运行了Martin的示例,得到了以下结果:

  • 目标。net 4, PASS
  • 针对。net 3.5, FAIL
  • 针对。net 3.5的RELEASE模式,PASS

遗憾的是,所有微软Bug报告的SO链接现在都死了,我还没能找到任何其他的。

这不是一个具体的答案;但是我不能把它作为评论发布。

我无法复制这个(VS 2012, . net 4.5, c# 5.0,所有安装的SP)。

我定义了这个异常类:

class MyException : Exception
{
    public MyException() { }
    public MyException(string message) : base(message) { }
}

和方法:

static void Throws<T>(Action action) where T : Exception
{
    try
    {
        action();
    }
    catch (T) { Console.WriteLine("got {0}", typeof(T)); }
    catch (Exception) { Console.WriteLine("got Exception"); }
}

,我已经这样测试了:

Throws<MyException>(() => { throw new MyException(); });
int result = 0;
Throws<DivideByZeroException>(() => result = result / result);

,输出为:

  • 草案。MyException
  • 系统。DivideByZeroException

所以(恕我直言)你应该去别的地方看看。