2011-11-22 6 views
5

私は最近、小さなタスクの配列を繰り返し実行する比較的複雑なアプリケーションをC#で書いています。最初にアプリケーションを起動したときに、入力したコードの多くが反復的であることがわかったので、必要に応じて呼び出すことができる別のヘルパークラスにアプリのロジックの大部分をカプセル化し始めました。C#アプリケーションで例外を処理する場所はどこですか?

言うまでもなく、私のアプリのサイズ(およびコードの量)は半分にカットされていました。しかし、私が進んでいくうちに、私のアプリケーションでは、繰り返し可能なように見えて、改善できるように見えた何かに気付きました。

私のヘルパークラスのほとんどのメソッドは、HttpWebRequestを作成しているか、ファイルに対して保存/削除操作を行っています。十分なスペースがないなどの理由で、コールが完了しない、またはファイルを保存できない可能性を処理する必要があると述べています。私が実行している問題は、メソッドの1つを呼び出すたびにtry/catchステートメントを書き続ける必要があることです。その上に、私はエラーメッセージを再入力する必要があります(または、最終的にステータスメッセージ。私はそれが成功したときも知りたいです)。

だからここに私が入力しているかのスニペットのようなものだ:

try 
    { 
    ItemManager.SaveTextPost(myPostItem); 
    } 
    // Majority of the time there is more than one catch! 
    catch 
    { 
    //^^^Not to mention that I have to handle multiple types of exceptions 
    //in order to log them correctly(more catches..ugh!) 
    MessageBox.Show("There was an error saving the post."); 
    //Perform logging here as well 
    } 

を私がこれまでに締結したものからは、次のとおりです。

  • 私にこれはやり過ぎ50の上にこれを記述することさ私のアプリの時間。 私はこれをヘルパークラスに含める必要があり、 のキャッチセットを含める必要があります。
  • しかし、どのように結果を知ることができますか?私はおそらく、エラー/成功メッセージを含む 文字列を返すことを考えていました。
  • 実際には、これらのタイプのメソッドでは、try/catchブロックでヘルパーメソッドを呼び出すメソッドを呼び出すメソッドは必要ありません。

このアプローチは正しいですか?これを行う別の方法がありますか?呼び出しメソッドでtry/catchを使用する必要がありますか?このような私の最初のショットは、このシナリオを扱った他の人が何を言っているか聞いてみたいと思っています。

+0

同様の質問が最近尋ねられました:http://stackoverflow.com/questions/8156530/exception-handling-in-method-definition-or-call/8156574#8156574 – Tudor

答えて

1

あなたが呼び出しているメソッドにtry/catchを入れても問題ないと思います。さまざまな方法で、エラーコード/成功コードを呼び出しコードに戻すことができます。 .NETとC#は列挙をうまく処理するので、ItemManager.SaveTextPost(myPostItem, out errorCode);があります。ここで、errorCodeは問題が発生したかどうかを知らせる列挙値になります。また、メソッドが成功した場合はboolをtrueに戻し、それ以外の場合はfalseを返すように簡単にすることもできます。あなたがその問題を扱うことができる多くの方法がありますが、私が心配している限り、メソッドにtry/catchを置くことは、やり方の好ましい方法です。

+0

+1は列挙された値を送り返します。私はそれが素晴らしい考えだと思う。どういうわけか、私は文字列hahaを送るより良い方法があることを知っていました。 – loyalpenguin

+0

私は 'SaveTextPost(myPostItem、out errorCode)'の方法では行かないでしょう。コードを使用している人にとっては混乱する可能性があり、エラー値の列挙を維持するのはずっと面倒です。また、エラーを処理するために設計された例外ではありませんか? 'true'と' false'が十分であれば、ブール値は返ってきます。 – Otiel

+0

例外はエラーのためのものですが、エラーごとに例外を投げることに頼るべきではありません。あなたが間違っていると予想されるものは正常に処理されるべきであり、例外的な出来事であるものは例外をスローするべきです(完璧な例はファイルシステムIOを処理しています - ファイルがどのような状態にあり、それに)。例外をスローするのは高価で、防御的なプログラミングの代わりにそれらを使用するのは、私の意見ではコーディングが悪いだけです。 –

1

AOPPostSharpのようなライブラリは、このようなクロスカッティングの問題を処理するように設計されています。

これらすべてのヘルパーメソッドで同じボイラープレートtry catch>を使用すると、複数のタイプの例外が処理される場合、それを行う1つのアスペクトを記述し、関連するすべてのメソッドを適切な属性で修飾することができます。

1

例外処理のための完全な単一の規則はないので、答えは次のとおりです。一般的に、例外を処理する方法がわかっている場合にのみ例外をキャッチする必要があります。あなたの例で私の最初の質問は、アプリケーションがこのエラーの後に実行を続けることができ、依然として有効な状態にある場合です。もしそうでなければ、ロギング後に例外を元に戻すべきです。次に、入れ子になっている例外について考えてみましょう。例外を捕捉し、別の例外に入れ子にして情報を追加し、例外をスローします。例外クラスとハンドラを慎重に設計する場合、ロギングと表示コードは予想よりもはるかに単純になります。しかし、詳細は明らかにアプリケーションによって異なります。

1

すべての引数が正しい場合は、ifブロックにチェックを入れて例外をスローする必要があります。必要に応じてヘルパーメソッドにtry catchブロックを実装し、例外をスローします。

最後に、try catchブロックすることにより、これらのヘルパーメソッドを囲みますが、この時点で、本当にキャッチ例外:終わり

try 
{ 
    ItemManager.SaveTextPost(myPostItem); 
    // SaveTextPost can throw some exceptions (that you know) 
} 
catch (Exception e) 
{ 
    // You know the exceptions that SaveTextPost can return, so threat them 
    // correctly 
    if (e is FileNotFoundException) 
     MessageBox.Show("The file was not found when saving the post."); 
    else if (e is ArgumentNullException) 
     MessageBox.Show("The post can't be null to be saved."); 
    else 
     MessageBox.Show("There was an error saving the post."); 
} 

は、あなたがエラーを処理して表示する必要がエラーメッセージが表示されます。 MessageBox.Showをヘルパーメソッドまたはヘルパーメソッドを呼び出すクラスに実装する必要があるかどうかのみを判断できます。
個人的には、コードを実行する開発者がヘルパーメソッドを使用することになっていると思いますので、エラーで何をしたいのかを決定させる必要があります。これは、ヘルパーメソッドで例外をスローすることを意味します。

+0

はい、あなたの呼び出しが既に例外を処理している場合は、try/catchブロックにメソッドを囲む目的になります。正直言って、私はそれから離れたいと思っています。 99.9%の確率で失敗する可能性があると思います... – loyalpenguin

+0

+1このような例外のタイプを判断することはできませんでした。何かが学んだ。私は間違いなく、開発者がメッセージを伝える方法(時には決してない)を彼らに任せなければならないということにも同意します。 – loyalpenguin

+2

あなたのやろうとしていることのために、このタイプの比較はできません。if(eがFileNotFoundExceptionです){} – iamkrillin

0

私の個人的な取り引き例外処理は.. try {} catch {}を意味します。

たとえば、「信頼できない」コード(モジュールまたはプラグイン)を呼び出すときは、常にtry catchを使用します。それ以外の場合は例外をキャッチしようとしている場合は、それで意味のあることを実行できることを確認してください。そうでない場合は、可能な限り、例外をバブルアップしてください。

開発者が例外をキャッチしてboolを返すアプリケーションをデバッグしようとするよりも悪いことはほとんどありません。 Just sayin '

1

Try/Catchは良い解決策です。 1つの提案、私はエラーの流れを止めるためにこれを使いたい:例外捕捉: try { } catch(Exception ex) { ShowExceptionError(ex); } 次に、すべての例外を単一のメソッドにスローし、そのメソッドでそれぞれのメソッドを処理させます。このようなの

種類:

private void ShowExceptionError(ex) 
{ 
    string errorMessage = "Type of error:" + ex.GetType().ToString(); 
    string stackTrace = ex.StackTrace(); 
    MessageBox.Show(errorMessage + "\n\n" + stackTrace); 
} 
1

これらの方法のすべては、偉大なオプションです。あなたがしたくないことの1つは、フロー制御のためにtry {} catch {}を使用することです。これは、このようなことを意味します(これもまた避けてください)。

Void SomeMethod() 
{ 
    try 
    { 
     while(somecondition) 
     { 
      try 
      { 
      } 
      catch (Exception ex) 
      { 

      } 
      } 
    } 
    catch (Exception ex) 
    { 
      ..... 
    } 

代わりに防御的にコードします。

関連する問題