【问题标题】:C# equivalent to VB.NET's Catch...WhenC# 相当于 VB.NET 的 Catch...When
【发布时间】:2010-09-15 22:07:47
【问题描述】:

在VB.NET中我经常Catch…When

Try
    …
Catch e As ArgumentNullException When e.ParamName.ToUpper() = "SAMPLES"
    …
End Try

是否有与 Catch…When 等效的 C#?

如果可能的话,我不想在catch 中使用if 语句。

【问题讨论】:

标签: c# vb.net exception-handling vb.net-to-c#


【解决方案1】:

在 C# 中没有与 Catch…When 等价的东西。你真的必须在你的catch 中使用if 语句,然后如果你的条件不满足则重新抛出:

try
{
    …
}
catch (ArgumentNullException e)
{
    if ("SAMPLES" == e.ParamName.ToUpper())
    {
        … // handle exception
    }
    else
    {
        throw;  // condition not fulfilled, let someone else handle the exception
    } 
}

【讨论】:

  • 我与 cruizer 和 Nicholas Mancuso 在一起,只需使用“throw”即可保留堆栈The Mistake Every C# Programmer Makes
  • @bob31334 只是异常对象中捕获的栈,然而程序的状态已经被修改,原来的栈被销毁,finally块已经执行(也就是说when过滤器运行在catch 语句级别而不是在处理程序中,这类似于 win32 API 中的 SEH)
【解决方案2】:

这不会重新创建与 VB Catch When 表达式相同的语义。有一个关键区别。 VB When 表达式在堆栈展开发生之前执行。如果您要在 when Filter 的位置检查堆栈,您实际上会看到引发异常的帧。

在 catch 块中有一个 if 是不同的,因为 catch 块在堆栈展开后执行。当涉及到错误报告时,这一点尤其重要。在 VB 场景中,您可以使用包括故障在内的堆栈跟踪崩溃。在 C# 中无法获得这种行为。

编辑:

就此主题写了detailed blog post

【讨论】:

  • 你确定吗?你可以只用'扔;'而不是 'throw e;'
  • 100% 和扔无关。它是当执行时调用的表达式。在 VB 中,它会在异常引发点仍在堆栈上时发生。
  • 在 c# 中,即使堆栈已卸载 - 异常对象 'e' 仍然具有可用的堆栈跟踪。但它可能没有在调试时提供整个堆栈那么有用。但是对于运行时登录信息堆栈跟踪就足够了?
  • 除了调试,可以通过勾选“抛出异常时中断”复选框在 C# 中更轻松地完成调试,这对于是否运行“finally”子句也很重要。
  • +1。 Microsoft .net 团队成员的一些其他博客文章链接。 .Net CLR 博客文章Catch, Rethrow and Filters - Why you should care?。也很感兴趣The good and the bad of exception filters
【解决方案3】:

此功能是针对 C# 6 发布的。现在可以编写

try { … }
catch (MyException e) when (myfilter(e))
{
    …
}

您可以立即下载Visual Studio 2015的预览版进行查看,或等待正式发布。

【讨论】:

    猜你喜欢
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 2013-10-24
    • 1970-01-01
    • 2018-06-29
    • 2019-06-17
    • 2021-09-22
    • 2012-09-10
    相关资源
    最近更新 更多