15

この質問は私がやりたいことに近いですが、完全にはありません。

次のコードを簡略化する方法はありますか?

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;
}

無駄に思えます。後でエラーをユーザーに報告する方法を変更したい場合、またはこれらのエラーをログに記録したい場合などは、5つの異なるキャッチブロックを変更する必要があります。私は何かが足りないのですか、それともこれはコードの再利用に対して露骨に反対ですか?

私は(あまりにも)怠惰になろうとしているだけですか?

4

11 に答える 11

24

使用できます:

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;
}
于 2009-08-20T09:55:38.703 に答える
8

例外が共通のスーパークラスを共有している場合は、スーパークラスをキャッチできます。

于 2009-08-20T09:53:35.803 に答える
3

はい、あなたは怠惰になろうとしていますが、怠惰はプログラマーの美徳の1 つなので、それは良いことです。

あなたの質問について:私が知っている方法はありませんが、利用可能な回避策がいくつかあります:

  • 例外に共通の祖先を与えます。あなたの場合、組み込みのように見えるので、これは不可能だと思います。
  • できる限り一般的な例外をキャッチします。
  • 処理コードを独自の関数に移動し、各 catch ブロックから呼び出します。
于 2009-08-20T09:55:46.550 に答える
2

完全を期すために:

VB では、条件付き例外処理を使用できます。

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

このようなCatchブロックは、C# とは異なり、指定された例外に対してのみ入力されます。

おそらく、C# の将来のバージョンでも同様の機能が提供されるでしょう (結局のところ、そのコードには特定の IL 命令があります)。

MSDN: 方法: Visual Basic の Catch ブロックでエラーをフィルター処理する

于 2009-08-20T10:48:36.380 に答える
2

これは面倒で、他の回答では適切な回避策が提案されています (@Lotfi を使用します)。

ただし、この動作は、C# の型安全性を考慮すると必須です。

これができるとします:

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

今、タイプはex何ですか?それらはすべて.Messageを継承しているため、持っSystem.Exceptionていますが、他のプロパティにアクセスしようとすると問題が発生します。

于 2009-08-20T10:00:33.763 に答える
2

複数のタイプの例外をキャッチする場合は、最も一般的なものから順に指定する必要があることに注意することも重要です。例外は、一致するリスト内の最初のものを見つけてそのエラーをスローします。他のエラーはスローされません。

于 2009-08-20T10:04:41.447 に答える
1

Check out the The Exception Handling Application Block from EntLib. They articulate a very nice policy and configuration based exception handling methodology that avoids large conditional logic blocks.

于 2009-08-21T07:49:20.330 に答える
0

できるよ

ex.GetType()

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;            
}
于 2009-08-20T09:52:44.980 に答える
0

基本クラスの例外をキャッチできます(すべての例外はから派生しますSystemException):

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

ただし、キャッチしたくない例外をキャッチしてしまう可能性があります。

于 2009-08-20T09:54:56.240 に答える
0

これらの例外のいくつかは予見できない可能性があることは理解していますが、可能な場合は独自の「プリエンプティブ」ロジックを実装してみてください。例外はコストがかかりますが、この場合はおそらく取引を妨げるものではありません。

たとえば、UnauthorizedAccessException がスローされることに依存するのではなく、Directory.GetAccessControl(...) を使用します。

于 2009-08-20T10:23:15.543 に答える
0

You could use delegates, this will do what you want:

EDIT: simplified a bit

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;
         }
    }
}

Your particular try/catch would be:

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;
于 2009-08-20T10:14:57.633 に答える