2

データ クラスの catch ブロックに次のパターンを使用していました。

} catch (OracleException e) {
    log.Error(e, e);
    ExceptionNotification.Show(e, "Platypus data not found for Platypus");
    throw;
}

(「ログ」は log4net です。その後に、派手な例外表示ダイアログが続きます)。

「スロー」を削除すると、「すべてのコードパスが値を返すわけではありません」というメッセージが表示されます

例外ブロックに到達した場合、返したいオブジェクト (OracleDataTable、List、Dictionary<>、またはカスタム クラス) は通常、null であるか、せいぜい気分が悪くなる可能性があります。コンパイラ?

4

4 に答える 4

5

戻り値の型を宣言するメソッドのすべてのコード パスは、値を返すか、例外をスローする必要があります。

スローしたくない場合は、適切な値を返す必要があります

} catch (OracleException e) {
    log.Error(e, e);
    ExceptionNotification.Show(e, "Platypus data not found for Platypus");
    return SomeMeaningfulReturnValue;
}

ただし、返すことができる値が実際に呼び出し元にとって意味のあるものでない限り ( nullを返し、「null は問題があったことを意味する」というコード コントラクトを発明するのではなく)、何か例外が発生したときに例外をスローするという規則に固執します。違う。

于 2012-08-16T22:01:18.683 に答える
2

決してコンパイラを軟化させないでください。彼らをボスにして、あなたが必要とすることを彼らにさせてください。

コンパイラは従順な性質を持っており、上司にされるのが好きです。あなたが彼らをなだめ始めた瞬間、彼らはあなたを助けなくなります。自分のパドルを持ってくる人もいます。

この質問をしなければならない場合は、おそらく間違ったアプローチをとっています。「例外を飲み込んだときにどのような値を返すか」の答えは、「この場所でこの例外を飲み込んだときに返す値として露骨に明らかな値」です。それほど明白なものがない場合は、飲み込んではいけません (「この例外をこの場所で飲み込んだ後、ループ内の明らかな場所から続行する」ことも同様です)。そして、「明らかな」ことが依然として間違っている可能性があるため、仮定を再確認してください。

コードを読んでいる人が、なぜそうではないのかを説明しない限り、悪いコードであると仮定して開始することはよくあることなので、飲み込んだ場合は明確にコメントする必要があります。

次のいずれかを行ったほうがよいでしょう。

throw;

例外を通過させます。何かがそれを処理するか、または何かが処理しないと、エラー メッセージとシャットダウンが表示されます (アプリケーションやエラーの可能性によっては、必ずしも悪いことではありません)。

throw e;

これはまったく同じ例外 (文字通り同じインスタンス) をスローしますが、呼び出したコードではなく、コードから発生していると見なされます。これが正しいことはめったにないので、明らかに間違っていると言う人もいます。私は同意しませんが、ケースがまれであることには同意します-嚥下のように、それが明らかな選択でない場合、それはほぼ間違いなく間違った選択であり、それが明らかな選択である場合でも、それは依然として間違った選択である可能性があります.

throw new ExceptionTypeAppropriateToThisMethodCall("a useful message");

また

throw new ExceptionTypeAppropriateToThisMethodCall("a useful message", e);

ここで、例外を、メソッドが呼び出し元のコードに提供するサービスにより密接に関連するものに変えます。2 番目の形式は、診断の良さのために内部例外をラップします。

場合によっては、アプリケーションを強制終了するか、アプリ ドメインをアンロードすることが最善の選択になることがありますが、それはほとんどの場合、例外を処理するものが何もないために発生します。

于 2012-08-16T22:34:52.613 に答える
1

何を返すことができるかは、失敗時に関数に何をさせたいか、またはその関数の呼び出し元がフォールトサインのように何を期待しているかによって異なります。

return null(投稿を考慮して)追加できます

  • 最初に呼び出し元に戻り値がnull

  • 2番目は例外を伝播しません(私が理解している限り、それはあなたが望むものです)

于 2012-08-16T22:02:20.267 に答える
1

例外をスローするか、値を返します。そのため、コンパイラは不平を言っています。特定のケースでどのパターンが最適に機能するかを判断し、それを採用して、呼び出しコードがそれを考慮して記述されていることを確認する必要があります。この特定のケースでは、例外をキャッチしているので、おそらく例外を伝播するだけです。おそらくすべきではないときに例外をスローしているOracleドライバーの手に負えない動作を何らかの形で補償していない限り。

「データが見つかりませんでした」または同様の状況は、「パスワードが間違っていたため、データベースにログオンできませんでした」とは異なります。

于 2012-08-16T22:06:32.447 に答える