代码之家  ›  专栏  ›  技术社区  ›  Matthew Scharley

你能在每个块中捕获多种类型的异常吗?[副本]

  •  15
  • Matthew Scharley  · 技术社区  · 17 年前

    This question is close to what I want to do ,但不完全在那里。

    有没有一种方法可以简化以下代码?

    private bool ValidDirectory(string directory)
    {
        if (!Directory.Exists(directory))
        {
            if (MessageBox.Show(directory + " does not exist. Do you wish to create it?", this.Text) 
                == DialogResult.OK)
            {
                try
                {
                    Directory.CreateDirectory(directory);
                    return true;
                }
                catch (IOException ex)
                {
                    lblBpsError.Text = ex.Message;
                }
                catch (UnauthorizedAccessException ex)
                {
                    lblBpsError.Text = ex.Message;
                }
                catch (PathTooLongException ex)
                {
                    lblBpsError.Text = ex.Message;
                }
                catch (DirectoryNotFoundException ex)
                {
                    lblBpsError.Text = ex.Message;
                }
                catch (NotSupportedException ex)
                {
                    lblBpsError.Text = ex.Message;
                }
            }
        }
    
        return false;
    }
    

    我只是想偷懒吗?

    11 回复  |  直到 9 年前
        1
  •  24
  •   Matthew Scharley    17 年前

    您可以使用:

    catch (SystemException ex)
    {
      if(    (ex is IOException)
          || (ex is UnauthorizedAccessException )
    // These are redundant
    //    || (ex is PathTooLongException )
    //    || (ex is DirectoryNotFoundException )
          || (ex is NotSupportedException )
         )
           lblBpsError.Text = ex.Message;
        else
            throw;
    }
    
        2
  •  8
  •   Benedict Cohen    17 年前

    如果异常共享一个公共的超类,那么你就可以捕获这个超类。

        3
  •  3
  •   soulmerge    17 年前

    the virtues of a programmer ,所以这很好。

    至于你的问题:我不知道,但有一些解决方法:

        4
  •  2
  •   Keith    17 年前

    然而,考虑到C#的类型安全性,这种行为是必须的。

    try
    {
        Directory.CreateDirectory(directory);
        return true;
    }
    catch (IOException, 
        UnauthorizedAccessException,
        PathTooLongException,
        DirectoryNotFoundException,
        NotSupportedException ex)
    {
        lblBpsError.Text = ex.Message;
    }
    

    现在是什么类型 ex .Message System.Exception ,但尝试访问它们的任何其他属性,就会出现问题。

        5
  •  2
  •   Audioillity    17 年前

        6
  •  2
  •   Konrad Rudolph    17 年前

    为了完整起见:

    Try
        …
    Catch ex As Exception When TypeOf ex Is MyException OrElse _
                               TypeOf ex Is AnotherExecption
        …
    End Try
    

    这样一个 Catch 与C#不同,块只会为指定的异常输入。

    MSDN: How to: Filter Errors in a Catch Block in Visual Basic

        7
  •  1
  •   JP Alioto    17 年前

    看看 The Exception Handling Application Block EntLib 他们阐述了一种非常好的基于策略和配置的异常处理方法,避免了大型条件逻辑块。

        8
  •  0
  •   Martin Liversage    17 年前

    SystemException ):

    try
    {
      Directory.CreateDirectory(directory);
      return true;
    }
    catch (SystemException ex)
    {
      lblBpsError.Text = ex.Message;
    }
    

        9
  •  0
  •   Polo    17 年前

    你可以

    看见 http://msdn.microsoft.com/en-us/library/system.exception.gettype.aspx

    编辑

    try            
    {                
        Directory.CreateDirectory(directory); 
        return true;           
    }            
    catch (Exception ex)            
    {   switch(ex.GetType())
             case .....
             case ..........
        blBpsError.Text = ex.Message;            
    }
    
        10
  •  0
  •   Neil    17 年前

    我理解其中一些例外情况可能无法预见,但在可能的情况下,请尝试实现自己的“先发制人”逻辑。例外情况是昂贵的,尽管在这种情况下可能不会破坏交易。

    例如,使用目录。GetAccessControl(…),而不是依赖于抛出未经授权的AccessException。

        11
  •  0
  •   andreialecu    17 年前

    编辑: 简化了一点

    static void Main(string[] args)
    {
        TryCatch(() => { throw new NullReferenceException(); }, 
            new [] { typeof(AbandonedMutexException), typeof(ArgumentException), typeof(NullReferenceException) },
            ex => Console.WriteLine(ex.Message));
    
    }
    
    public static void TryCatch(Action action, Type[] exceptions, Action<Exception> catchBlock)
    {
        try
        {
            action();
        }
        catch (Exception ex)
        {
             if(exceptions.Any(p => ex.GetType() == p))
             {
                 catchBlock(ex);
             }
             else
             {
                 throw;
             }
        }
    }
    

    您的特定尝试/捕捉将是:

    bool ret;
    TryCatch(
        () =>
            {
                Directory.CreateDirectory(directory);
                ret = true;
            },
        new[]
            {
                typeof (IOException), typeof (UnauthorizedAccessException), typeof (PathTooLongException),
                typeof (DirectoryNotFoundException), typeof (NotSupportedException)
            },
        ex => lblBpsError.Text = ex.Message
    );
    
    return ret;