異常処理の最良の習慣

3930 ワード

良好に設計されたエラー処理コードブロックセットは、このようなアプリケーションがエラーを処理しているため、プログラムをより丈夫にし、より少ないクラッシュ機会に直面させることができる.次のリストには、例外処理の最適な習慣に関する推奨事項が含まれています.
  • try/catchブロックをいつ設立するか知っています.たとえば、プログラムを使用して、例外処理以外の条件が発生する可能性があることを確認できます.他の場合、例外処理を適切に使用してエラー条件をキャプチャする必要があります.次の例では、if文を使用して、接続が閉じられているかどうかを確認します.この方法を使用すると、接続が閉じられていない場合に異常な方法を投げ出す代わりに使用できます.
       if(conn.State != ConnectionState.Closed)
          conn.Close();
    次の例では、接続が閉じられていない場合、例外が放出される.
       try {
         conn.Close();
       }
       catch(InvalidOperationException ex) {
         //              。
       }
    あなたが選択した方法は、イベントの発生をどのように常に期待するかに依存します.イベントが実際の例外であり、予期せぬファイルの最後などのエラーである場合、通常の場合に実行されるコードがより少ないため、例外処理を使用するのがより良いです.このイベントが頻繁に発生する場合は、プログラム可能な方法を使用してエラーをチェックすることが望ましい.この場合、異常が発生すると、より長い処理時間が得られる.
  • try/finallyブロックを使用して、潜在的に発生する可能性のある異常を包囲し、catch文を1つの位置に集約するコードを使用します.これにより、try文に異常が発生し、finally文はリソースの割り当てをオフまたはキャンセルし、catch文は1つのセットの位置から異常を処理します.
  • は、catchブロック内の異常を常に最も特殊から最も特殊でない順序で並べ替える.この技術は、より一般的なcatchブロックに伝達される前に、特殊な異常を処理する.
  • 単語[Exception]を異常クラス名の末尾とする.例:
    public class MyFileNotFoundException : ApplicationException {
    }
  • ユーザー定義の例外を作成する場合は、アプリケーションドメインを越えて発生した例外を含むリモート・コード実行に使用できる例外のメタデータを確保する必要があります.例えば、Application Domain Aは、例外を投げ出すコードを実行するApplication Domain Bを作成したとする.アプリケーションDomain Aが適切に例外をキャプチャして処理するためには、アプリケーションDomain Bによって投げ出された例外を含むアセンブリセットを見つける必要があります.アプリケーション・Domain Bがアプリケーション・ベースの下にアセンブリ・セットに含まれる例外を放出しますが、アプリケーション・Domain Aのアプリケーション・ベースの下ではない場合、アプリケーション・Domain Aはその例外を見つけることができず、共通言語の実行時にFileNotFoundExceptionも放出されます.このような状況を回避するには、例外情報を含むアセンブリセットを2つの方法で配置できます.
  • は、2つのアプリケーションドメインによって同時に共有される共通のアプリケーションベースにアセンブリセットを配置する-または-
  • .
  • ドメインが共通アプリケーション・ベースを共有していない場合、アセンブリ・セットに強い名前でタグを付けて異常情報を含み、アセンブリ・セットをグローバル・アセンブリ・キャッシュに配置する.
  • C#とC++では、自分の異常クラスを作成するときに少なくとも3つの共通のコンストラクタを使用します.例については、[ユーザ定義を使用した例外]を参照してください.
  • 多くの場合、予め定義された例外タイプを使用することができる.新しい例外タイプは、プログラム可能な場合にのみ定義されます.新しい例外クラスを導入して、プログラマがその例外クラスに基づくコードで他の動作を実行できるようにします.
  • アプリケーションのほとんどは、Exceptionクラスからカスタム例外を派生させることができます.これは、カスタム例外がApplicationExceptionクラスから派生すべき最初の考慮です.しかし、習慣から重要な価値が増すことは発見されなかった.
  • は、各例外にローカライズされた記述文字列を含む.ユーザがエラーメッセージを見たとき、これは異常クラスよりも放出されたクラスから派生した記述文字列である.
  • は、最後の句読点を含む正しい文法エラーメッセージを使用する.例外記述文字列の各文は、ピリオドで終わる必要があります.
  • は、プログラム可能アクセスのためのException属性を提供する.例外的な追加情報(文字列の記述を除く)は、追加情報が有用なプログラマブルな場合にのみ含まれる.
  • は、非常に共通のエラーでnullを返します.たとえば、File.Openはnullを返し、ファイルが見つからない場合は例外を投げ出します.ファイルが発見されたら.
  • は、通常の使用から異常なクラスを放出しないように設計されている.たとえば、FileStreamクラスは、ファイルの最後に到達したかどうかを検出する他の方法を暴露します.これにより、ファイルの最後に読み込まれた場合、例外を放出することが回避されます.次の例では、ファイルの最後に読み込む方法を示します.
    class FileRead {
        void Open() {
            FileStream stream = File.Open("myfile.txt", FileMode.Open);
            byte b;
    
            // ReadByte   EOF    -1。
            while ((b == stream.ReadByte()) != true) {
                //     。
            }
        }
    }
  • は、属性セットまたはメソッド呼び出しがオブジェクトの現在の状態を適切に提供していない場合に、InvalidOperationExceptionを放出する.
  • は、無効なパラメータが渡された場合、ArgumentExceptionまたはArgumentExceptionから派生したクラスを投げ出します.
  • スタックトラッキングは、例外が投げ出された文から開始し、その例外をキャプチャしたcatch文から終了する.どこにthrow文を保存するかを決めたとき、この事実を理解しなければなりません.
  • は、通常、クラスがその実装中の異なる位置から同じ異常を放出する共通の方法のために、異常確立器法を使用する.追加のコードを回避するには、例外を作成して返す補助方法を使用します.たとえば、
    class File {
        string fileName;
        public byte[] Read(int bytes) {
            if (!ReadFile(handle, bytes))
                throw NewFileIOException();
        }
        FileException NewFileIOException() {
            string description = //          ,   fileName。
            return new FileException(description);
         }
    }
    または例外のコンストラクタを使用して例外を確立します.これは、ArgumentExceptionなどのグローバル例外クラスに適しています.
  • は、エラーコードまたはHRESULTを返す代わりに異常を放出する.
  • 異常が放出されたときに中間結果をクリーンアップする.呼び出し者は,異常がメソッドから投げ出されたときに負の影響を及ぼさないと仮定できるはずである.