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!!!");
}
}
}
}
您不是第一个遇到这个问题的人。这个问题很相似。如果你仔细研究答案和链接,就会发现这是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
所以(恕我直言)你应该去别的地方看看。