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

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

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

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

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


当前回答

为了完整起见,自.NET 4.0以来,代码可以重写为:

Guid.TryParse(queryString["web"], out WebId);

TryParse从不抛出异常,如果格式错误,则返回false,将WebId设置为Guid.Empty。


由于C#7,您可以避免在单独的行中引入变量:

Guid.TryParse(queryString["web"], out Guid webId);

您还可以创建用于解析返回元组的方法,这些方法在.NET Framework 4.6版之前尚不可用:

(bool success, Guid result) TryParseGuid(string input) =>
    (Guid.TryParse(input, out Guid result), result);

并像这样使用它们:

WebId = TryParseGuid(queryString["web"]).result;
// or
var tuple = TryParseGuid(queryString["web"]);
WebId = tuple.success ? tuple.result : DefaultWebId;

当在C#12中实现out参数的解构时,这个无用答案的下一个无用更新就来了

其他回答

怎么样

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

@密歇根州

代码的略微修订版本:

catch (Exception ex)
{
   Type exType = ex.GetType();
   if (exType == typeof(System.FormatException) || 
       exType == typeof(System.OverflowException)
   {
       WebId = Guid.Empty;
   } else {
      throw;
   }
}

字符串比较既丑陋又缓慢。

在C#6中,推荐的方法是使用异常过滤器,下面是一个示例:

 try
 {
      throw new OverflowException();
 }
 catch(Exception e ) when ((e is DivideByZeroException) || (e is OverflowException))
 {
       // this will execute iff e is DividedByZeroEx or OverflowEx
       Console.WriteLine("E");
 }

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

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
}

警告和警告:另一种功能性风格。

链接中的内容不会直接回答您的问题,但将其扩展为以下内容很简单:

static void Main() 
{ 
    Action body = () => { ...your code... };

    body.Catch<InvalidOperationException>() 
        .Catch<BadCodeException>() 
        .Catch<AnotherException>(ex => { ...handler... })(); 
}

(基本上提供另一个返回自身的空Catch重载)

更大的问题是为什么。我不认为这里的成本大于收益:)