2009-08-03 7 views
17

私はメソッドの数を持つクラスを持っていて、それらのために1つの例外ハンドラを持ちたいと思っています。 これらのメソッドには非常に多くのものがあり、それらはそれぞれ異なるパラメータを持っているため、それぞれのtry/catchを書くのは面倒です。クラスのすべての例外のための1つの例外ハンドラ

多分、私はそれをすべて処理するクラス例外ハンドラを持つことでそれを行う方法を知っていますか?

UPDATE:


あなたの多くは、なぜ私に尋ねます。その理由は、さまざまな方法でデータソースを呼び出すためです。 私のクラスは、関数getData1、gedData2、getData3、getData4、....、getDataNを持っています。問題は、接続がまだ開いていて新しい接続を作成するのが非常に高価であるかどうかを確認する方法がないことです。だから私は接続を再利用しようとしています、そして、次の呼び出しの接続が失敗した場合、私はこれをキャッチして、再接続して、やり直します。だから私はこのtry/catchブロックが必要なのです。すべての機能のためにこれを行うには

try{  
    datasource.getData() 
} 
catch(ConnectionException) 
{ 
    datasource.Connect(); 
    datasource.getData() 
} 

おかげ

+0

私はそれが古い質問です知っているが、私はほとんどの回答に同意するものの、ことを言いたかったですその質問が尋ねられた日に提出された以下の質問には、この能力が非常に役に立つ時があります。私は別のシナリオがあるので、この質問を見つけました。ジャック・アランの答えは私のシナリオではうまくいきませんが、それは他の状況でも役に立ち、非常に賢いですから、私はそれを上回りました。つまり、Jackの「ソリューション」を使用する前に、これを必要としないようにコードを構造化する他の方法がないことを確認してください。 –

+0

このような仕組みはなく、IMHOは存在してはいけません。制御フローがどのように引き渡されるかとは一貫していません。あなたがしなければならないことが「醜い」ということは重要ではありません。あなたがした解決策が、余分なコードを書くことを必要とすることは重要ではありません。重要なことは、分かりやすいソフトウェアを書くことができ、後で、あなた(または他の誰か)が元の詳細を忘れてしまったときに維持できることです。例外が発生したときにメソッドが何らかの処理を行う必要がある場合、メソッドには何をすべきかが記載されている必要があります。これは良いことです。 – ToolmakerSteve

+0

ところで、私はこれが大きな質問だと思うので、質問をアップアップしました。それは正統であり、他人にとってこれをやりたいと思っています。なぜこれを行う方法がないのか、何をすべきかを理解していること(理解していないにもかかわらず、あなたの質問にはあなたがしている)を理解することは、他者にとって有益なことです。 – ToolmakerSteve

答えて

19

あなたは、次の例のように1つのtryキャッチにあなたの方法のコードを渡すために、デリゲートを使用することができます。

private void GlobalTryCatch(Action action) 
    { 
     try 
     { 
      action.Invoke(); 
     } 
     catch (ExpectedException1 e) 
     { 
      throw MyCustomException("Something bad happened", e); 
     } 
     catch (ExpectedException2 e) 
     { 
      throw MyCustomException("Something really bad happened", e); 
     } 
    } 

    public void DoSomething() 
    { 
     GlobalTryCatch(() => 
     { 
      // Method code goes here 
     }); 
    } 
1

私はないと思います。 try/catchを呼び出し側に移動することはできますが、それはあまり良い設計ではありません。

public class MyClass {} 
public class MySafeClass { 
    public void CallMethod(string name, object[] param) { 
     Type t = typeof(MyClass); 
     MyClass mc = new MyClass(); 
     try { 
      t.GetMethod(name).Invoke(mc, param); 
     } 
     catch { 
      //...; 
     } 
    } 

}

しかし、あなたはいけない:このように、メソッドを呼び出すために別のクラスにそれを分離し、リフレクションを使用する方が良いかもしれません!それはあまり良いことではありません。

別の方法

はまだ戻って、ユーザに、などの例外をスローするために、単一の方法を try/catchを使用しますが持っている:

public class MyClass { 
    void DoException(string message) { 
     throw new Exception(message); 
    } 
} 

しかし、それはまだはその良いオプションではありません。

メッセージが1つのtry/catchで全体のメソッドをラップしたとしても、なぜそれが醜いのか分かりません。実現可能かもしれない。

それを残すだけで、発信者に返信することも可能です(おそらくtry/finally)。

特にVisual StudioとSharpDevelopのスニペットでは、すべてを試してみるのは難しいことではありません。

+0

お返事ありがとうございます。多分あなたは私の理由を見ることができる質問の更新を見て。 – husayt

1

これはデザインに問題があるようです。あなたが捕まえようとしている例外と、それを試して助けてくれる理由を正確に説明できますか?

+0

はい、おそらく私はより多くの文脈を与える必要があります、質問に私の更新をしてください。 – husayt

1

例外は実際にはクラス関連ではなく、メソッド/コールスタック指向です。オブジェクトは、一般に、それ自身のメソッドから例外を処理しようとはしません。これらのメソッドを呼び出すのは、呼び出し側の責任です。

0

私はこれを例外処理の重大な誤用であると考えていますが、あなたはロガーまたはsthを追加したい場合を除いて、あなたのメインメソッドについてtry/catchを入れたいかもしれません。私はとにかくあなたは、単一のメソッドを使用して、クラス内のすべての例外を処理から利益を得ることができる理由は、何らかの理由(あなたは手の込んだことができますか?私は好奇心が強い...)

を把握することはできません

+0

私はそのクラスのために何かが必要であり、そのクラスの中で扱われます。 Thnks – husayt

12

は、使用することができますAOP(アスペクト指向プログラミング)技術を使用して、クラスのメソッドの周りに例外処理コードを(静的にまたは実行時に)挿入します。

あなたのクラスのメソッドに属性を使用して設定することができPostSharpと呼ばれる優れた組立後処理ライブラリがあります:

あなたは(PostSharpのウェブサイトから)このような側面を定義することがあります。

public class ExceptionDialogAttribute : OnExceptionAspect 
{ 
    public override void OnException(MethodExecutionEventArgs eventArgs) 
    { 
     string message = eventArgs.Exception.Message; 
     MessageBox.Show(message, "Exception"); 
     eventArgs.FlowBehavior = FlowBehavior.Continue; 
    } 
} 

そして、あなたは例外を見たい方法で、このような に属性を適用します:

public class YourClass { 

    // ... 

    [ExceptionDialog] 
    public string DoSomething(int param) { 
     // ... 
    } 
} 

また、このように、クラス全体に属性を適用することができます。これは、クラス内のすべてのメソッドにアドバイス(例外処理コード)を適用します

[ExceptionDialog] 
public class YourClass { 
    // ... 
    public string DoSomething(int param) { 
     // ... 
    } 
    public string DoSomethingElse(int param) { 
     // ... 
    } 
} 

+1

良い答え。ちょうどFYI、PostSharpが仮想メソッドのOnExceptionシグネチャをOnException(MethodExecutionArgs eventArgs)に変更したようです。 – joshmcode

+0

私はこのために私のユースケースを追加したい、私はゲームのためのMODを作成しています。私がキャッチしなかった例外がスローされた場合、私は自分自身の登録を解除し、エラーを記録する(ゲームをクラッシュさせるのではなく)。これは便利です。 –

関連する問題