2011-07-28 6 views
1

私はtry/catch/finallyをif/elseのように動作させるように設定しようとしています。私はこの単純なことを行う最もエレガントな方法がわからない。C#try/catch/finallyをif/elseのように動作させる最も良い方法は何ですか?

public bool login() 
{ 
bool isLoggedIn = false; 
if (connectToServer(Path,username,password)) // if successful 
    { 
    isLoggedIn = true; 
    } 
    else 
    { 

    } 

return isLoggedIn; 
} 

ここでは例外について試したことがあります。

2行目の "isLoggedIn"は実行されますが、前の行ではエラーが発生しても例外が発生します。私の考えは「例外がスローされた場合、その行を実行したくない」という質問です。この時点で例外オブジェクトにアクセスしてテストすることはできますか(それとも範囲外ですか)。旧Cコーダは、私は単純なことを行うには、「#cがそれを維持」しようとしています。私はちょうど私のスキルを完璧し、「ベストプラクティス」に沿ったものにしたい。 おかげ DTM

+5

'try/catch'を' if/else'のように動作させたい場合は、間違っています。制御フローに例外を使用しないでください。 –

+0

あなたのアイデアやアプローチに感謝します。私は今、仕事をする良いチャンクを持っています。最後の文に対しては –

答えて

10

んが、それはしませんん実行取得、例外を処理するために、高価なコンテキストスイッチがあるよう。しかし、これは悪い習慣です。あなたが唯一例外例で例外を使用する必要があります。

私は2つのアプローチを組み合わせて検討する。

+0

+1です。 – John

+1

+1全体の答えです。フローの制御には例外を使用しません。 – aepheus

0

connectToServerは、成功しなかった場合はmyConnectionExceptionを投げるべきです

4

このようなことをすると何が問題になるでしょうか?

bool isLoggedIn = false; 

try 
{ 
    isLoggedIn = connectToServer(Path, username, password); 
} 
catch (ExceptionType1 ex1) 
{ 
    //Recover from this exception type. 
} 
catch (ExceptionType2 ex2) 
{ 
    //Recover from this exception type. 
} 

例外はif文の「置き換え」ではありません。それらはエラー状態を処理するためのものであり、エラー状態が発生した場合にはそれらを使用してアプリケーションのフローを制御することは確かにお勧めできません。少なくとも遅いですし、フローを制御するためにそれらを使用すると、実際にアプリケーションを失敗させたいときに実際の実際のエラーを隠すことがあります。

EDIT: @Anthony Pegramが以下のコメントに言及しているように、単一のキャッチブロック内のすべての例外タイプを処理することは悪い習慣です(私はあまりにも頻繁に罪を犯しています)。実際に具体的に扱いたいと思うかもしれません。

+1

私は、コードスニペットの 'catch'部分には反対します。答えのテキストが暗示しているように、あなたの意図は間違いありませんが、コード内のフレーズは有害です。代わりに、単純に上にバブルする必要があるため、*可能なエラー*ではなく対処できる狭く定義された例外をキャッチするように促すべきです。 –

+1

@Anthony - あなたは正しい。それは私の意図ではないが、あなたは良い点を作って答えを明確にした。 –

0

try/catchブロックをconnectToServerに移動することを強くお勧めします。前述したように、コンテクストの切り替えは恐ろしいオーバーヘッドであるため、プログラムフローを例外で制御するべきではありません。

connectToServerは常にtrueまたはfalseを返します(内部でエラーをキャッチしてfalseを返します)。単に:

return connectToServer(Path,username,password); 
+0

...次のコードがこの例外によって引き起こされた予期しない結果や望ましくない結果を生成しない場合は、例外が発生する可能性があります。 (さて、他の場所にキャッチされる可能性がありますが、キャッチする必要があります) – Beachwalker

+0

私の意見では、エラーをより一般的に処理し、エラーを防ぐために検出と検証を使用する方が良いです。あまりにも頻繁に私は、検出と検証の代わりにtry/catchが使用されていることがわかります。人々は呼び出しているコードを理解しておらず、try catchブロックでラップするだけです... – aepheus

+0

たとえば、この場合、connectToServerはすべてのデータアクセスの問題(エラーを含む)を処理し、trueを返しますまたはfalse。 connectToServerのパラメータを検証し、パラメータが期待どおりであることを確認するためにはログインする必要があります。 – aepheus

-1

これは機能しますが、実行しないでください。あなたの最善の策は、次のようにコード化することです:

public bool login() 
{ 
    return connectToServer(Path,username,password); 
} 

短くて甘い。例外は、例外的な場合を除いて使用することは非常に悪いです。障害が発生した例外的な機会が例外で拾ったが、時間のほとんど例外意志されることを意味

public bool login() 
{ 
    try 
    { 
     return connectToServer(Path,username,password); 
    } 
    catch(exception ex)//or the specific exception you are after 
    { 
     return false; 
    } 
} 

:あなたはその後、ConnectToServer関数の例外をピックアップする場合はもちろん、あなたのようなものを使用することができます呼び出されません。それはまだ偽であるように、例外がスローされた場合、接続コールが例外をスローした場合

0

この単純な例では

isLoggedIn = true; 

は(初期化など)に達していません。たとえキャッチされた例外タイプではないとしても、trueに設定するisLogginの部分には決して到達しません。

前述のとおり、if/then/elseまたはswitch/caseの代わりにexceptionを使用しないでください。 isLoggedInをtrueに設定した後にコードにもっと多くのメソッド呼び出しがある場合は、キャッチでこれが返された結果になるため、これをfalseにリセットする必要があります。

ところで、c#やi C++では例外を使用するルールに違いはありません。これは両方の言語に共通するようです。

関連する問題