不鼓励只捕获System.Exception。相反,只应捕获“已知”异常。

现在,这有时会导致不必要的重复代码,例如:

try
{
    WebId = new Guid(queryString["web"]);
}
catch (FormatException)
{
    WebId = Guid.Empty;
}
catch (OverflowException)
{
    WebId = Guid.Empty;
}

我想知道:是否有一种方法可以捕获两个异常,并且只调用WebId=Guid.Empty调用一次?

给定的示例相当简单,因为它只是一个GUID。但是想象一下,在代码中,您多次修改一个对象,如果其中一个操作预期失败,您希望“重置”该对象。然而,如果有意外的异常,我仍然想把它推得更高。


当前回答

想在这条已经很长的线索上加上我的简短回答。还没有提到的是catch语句的优先顺序,更具体地说,您需要了解您试图捕获的每种类型的异常的范围。

例如,如果您使用“catch-all”异常作为异常,它将优先于所有其他catch语句,您显然会遇到编译器错误。但是,如果您颠倒了catch语句的顺序(我认为这有点反模式),您可以将catch-allException类型放在底部,这将捕获任何在尝试中不适合更高级别的异常。。捕捉块:

            try
            {
                // do some work here
            }
            catch (WebException ex)
            {
                // catch a web excpetion
            }
            catch (ArgumentException ex)
            {
                // do some stuff
            }
            catch (Exception ex)
            {
                // you should really surface your errors but this is for example only
                throw new Exception("An error occurred: " + ex.Message);
            }

我强烈建议大家阅读此MSDN文档:

异常层次结构

其他回答

           try
           {
                WebId = new Guid(queryString["web"]);
           }
           catch (Exception ex)
           {
                string ExpTyp = ex.GetType().Name;
                if (ExpTyp == "FormatException")
                {
                     WebId = Guid.Empty;
                }
                else if (ExpTyp == "OverflowException")
                {
                     WebId = Guid.Empty;
                }
           }

也许试着让你的代码保持简单,比如把公共代码放在一个方法中,就像你在代码的任何其他不在catch子句中的部分所做的那样?

例如。:

try
{
    // ...
}
catch (FormatException)
{
    DoSomething();
}
catch (OverflowException)
{
    DoSomething();
}

// ...

private void DoSomething()
{
    // ...
}

我会怎么做,试图找到简单而美丽的模式

怎么样

try
{
    WebId = Guid.Empty;
    WebId = new Guid(queryString["web"]);
}
catch (FormatException)
{
}
catch (OverflowException)
{
}

这是马特的答案的变体(我觉得这有点干净)。。。使用一种方法:

public void TryCatch(...)
{
    try
    {
       // something
       return;
    }
    catch (FormatException) {}
    catch (OverflowException) {}

    WebId = Guid.Empty;
}

将引发任何其他异常,代码WebId=Guid.Empty;不会被击中。如果您不希望其他异常使您的程序崩溃,只需在其他两个捕获之后添加这个:

...
catch (Exception)
{
     // something, if anything
     return; // only need this if you follow the example I gave and put it all in a method
}

C#9的更新

使用C#9中的新模式匹配增强功能,可以缩短异常过滤器中的表达式。现在,捕获多个异常很简单,如下所示:

try
{
    WebId = new Guid(queryString["web"]);
}
catch (Exception e) when (e is FormatException or OverflowException)
{
    WebId = Guid.Empty;
}