Catch multiple exceptions at once?

前端 未结 27 2489
夕颜
夕颜 2020-11-22 11:31

It is discouraged to simply catch System.Exception. Instead, only the "known" exceptions should be caught.

Now, this sometimes leads to unnecce

27条回答
  •  猫巷女王i
    2020-11-22 12:05

    If you don't want to use an if statement within the catch scopes, in C# 6.0 you can use Exception Filters syntax which was already supported by the CLR in previews versions but existed only in VB.NET/MSIL:

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

    This code will catch the Exception only when it's a InvalidDataException or ArgumentNullException.

    Actually, you can put basically any condition inside that when clause:

    static int a = 8;
    
    ...
    
    catch (Exception exception) when (exception is InvalidDataException && a == 8)
    {
        Console.WriteLine("Catch");
    }
    

    Note that as opposed to an if statement inside the catch's scope, Exception Filters cannot throw Exceptions, and when they do, or when the condition is not true, the next catch condition will be evaluated instead:

    static int a = 7;
    
    static int b = 0;
    
    ...
    
    try
    {
        throw new InvalidDataException();
    }
    catch (Exception exception) when (exception is InvalidDataException && a / b == 2)
    {
        Console.WriteLine("Catch");
    }
    catch (Exception exception) when (exception is InvalidDataException || exception is ArgumentException)
    {
        Console.WriteLine("General catch");
    }
    

    Output: General catch.

    When there is more then one true Exception Filter - the first one will be accepted:

    static int a = 8;
    
    static int b = 4;
    
    ...
    
    try
    {
        throw new InvalidDataException();
    }
    catch (Exception exception) when (exception is InvalidDataException && a / b == 2)
    {
        Console.WriteLine("Catch");
    }
    catch (Exception exception) when (exception is InvalidDataException || exception is ArgumentException)
    {
        Console.WriteLine("General catch");
    }
    

    Output: Catch.

    And as you can see in the MSIL the code is not translated to if statements, but to Filters, and Exceptions cannot be throw from within the areas marked with Filter 1 and Filter 2 but the filter throwing the Exception will fail instead, also the last comparison value pushed to the stack before the endfilter command will determine the success/failure of the filter (Catch 1 XOR Catch 2 will execute accordingly):

    Also, specifically Guid has the Guid.TryParse method.

提交回复
热议问题