2011年1月30日日曜日

C#での例外処理コードの基本

C#コーディングで例外をどう扱うか。

普通はこうなる。
<A.防止可能か?>
├─(yes)─→ [B.防止するコードを書く]
(no)
└→<C.予見可能か?>
├─(yes)─→ [D. catch して処理するコードを書く]
(no)

[E. スルー]


A. 防止可能か?
例えば、「パラメータで null を渡されたら ArgumentNullException を投げる」ってドキュメントに書いてあったり、ソースコード上自明もの(バグも含む)だったり、例外発生の条件が分かっていて、そうならないようなコードを書ける場合は、防止可能と言う事になる。

B.防止するコード
A を満たす場合に、例外を発生させないようにコーディングする。

C.予見可能か?
防止できず、つまり実行するまで分からないが、状況によっては発生する事が分かっている例外状況を、「予見可能である」とする。例えば、ファイルを開くときの FileNotFoundException など。

D. catch して処理するコード
C で可能性が認められた例外については、catch してハンドリングするコードを書く。

E. スルー
防止も予見もできないものについては、復旧処理のしようも無いので、無理にアプリを動かし続けて誤動作による事態悪化を招くより、スルーしてアプリが停止するに任せる。書いてもせいぜい、AppDomain の UnhandleException イベントくらい。

この手順は、以下の URL で FxCop の開発者が詳説していたりもする。
http://blogs.msdn.com/b/codeanalysis/archive/2006/06/14/631923.aspx

まあ、普通のプログラマにとっては、いつも実践している通りの、言われるまでもない当たり前のコーディングじゃないだろうか。今更感満載で、「他にやり様あったっけ?ないでしょ?」てな感じになっちゃうと思う。

で、これを踏まえた上で、例えば、メソッドの API リファレンスに例外が沢山書いてあったらどうしようとか、catch 節もちゃんとテストしましょうだとか、finally を活用しましょうとか、いろいろな細かい事が生じてくる。

====
というのが、普通に計算機科学を勉強して、普通にプログラミングを習得して、普通にC#を書いてる人の自然なコーディングプラクティスだと思うのだけど、底辺プロジェクトでは、この基本フローの段階で物言いがつく事がある。

曰く
「うちのアプリは何があっても落とさないポリシーだから、E のスルーは容認できない。未知の例外はもみ消して無かった事にするのが我々の流儀である。」と。

・・・いや、それ、マジで言ってんのかと。

次は、これについて考えてみる。

0 件のコメント:

コメントを投稿