我正在对代码进行一些单元测试,这些代码可能会根据输入引发许多异常。所以我尝试了类似下面的代码:(简化示例)
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托管过程的一个特点?
答案 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
答案 1 :(得分:8)
没有Debug
丑陋的解决方法(您可以添加#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,在那种情况下,第一个处理程序得到了击中。
修改强>
正如其他人所指出的,更多的是在调试器中运行它而不是特定类型