0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

続・公式ドキュメントに学ぶ!例外処理のベストプラクティス

Last updated at Posted at 2025-05-04

前回記事の続きです

👇前回記事

Microsoft公式ドキュメントを参考に例外処理のベストプラクティスを学んでいきます

例外スロー時のベストプラクティス

前回は例外を受け取る側のベストプラクティスをまとめましたが、次は例外をスローする際の手法に触れていきましょう💪

.NET標準の例外クラスを使用すべし

事前定義の例外クラスが適用されない場合に限り独自の例外クラスを導入すべきとされています

ということは、.NET標準で定義されている例外以外はなるべく使用しないようにしましょうということですね

考えられる理由としては以下の通り

  • 全世界共通で使用されているフレームワークのため、エンジニアごとに認識の相違が起きにくい
  • 独自クラス例外はクラスが何を表しているのか解析が必要であり、デバッグが大変
  • コーディングに統一性が生まれ、保守性が高くなる

標準の例外クラスの代表例

例外クラス名 内容・説明
ArgumentException メソッドに渡された引数が不正な場合にスローされる。
ArgumentNullException 引数がnullであってはならない場合に、nullが渡されたときにスローされる。
ArgumentOutOfRangeException 引数が許容範囲外の場合にスローされる。
InvalidOperationException オブジェクトの状態が無効な場合に操作が実行されたときにスローされる。
NullReferenceException nullオブジェクトのメンバーにアクセスしようとした場合にスローされる。
IndexOutOfRangeException 配列やコレクションのインデックスが範囲外の場合にスローされる。
FormatException 値の書式が無効な場合にスローされる。
NotImplementedException 呼び出されたメソッドやプロパティが実装されていない場合にスローされる。
NotSupportedException メソッドや操作がサポートされていない場合にスローされる。
TimeoutException 操作が指定時間内に完了しなかった場合にスローされる。
IOException 入出力エラーが発生した場合にスローされる。
FileNotFoundException 指定したファイルが見つからない場合にスローされる。

意図的にスローすべきでない標準例外

ただ、AccessViolationException, IndexOutOfRangeException, NullReferenceException, StackOverflowException などは開発者が意図的にスローすべきでないとされています

これらの例外はCLRによって自動的にスローされる例外であって、回復困難なエラーであることが多いからです

詳細は以下に記載されています

例外ビルダーメソッドを使用すべし

様々な場所から同じ例外がスローされるため、例外を作成して返すビルダーメソッドを利用しましょう

実装例(公式ドキュメントより引用)

class FileReader
{
    private readonly string _fileName;

    public FileReader(string path)
    {
        _fileName = path;
    }

    public byte[] Read(int bytes)
    {
        // 例外をスローさせる場合はビルダーメソッドを呼び出す
        byte[] results = FileUtils.ReadFromFile(_fileName, bytes) ?? throw NewFileIOException();
        return results;
    }

    /// <summary> FileReaderExceptionを作成して返すビルダーメソッド </summary>
    static FileReaderException NewFileIOException()
    {
        string description = "My NewFileIOException Description";

        return new FileReaderException(description);
    }
}

こうすることで毎回例外を定義することなく、ルールが統一された例外を作成することができます

メッセージを適切に設定すべし

例外を生成する際のコンストラクタ引数にメッセージを含めることができます。引数で渡された文字列はException.Messageのプロパティに割り当てられます。

メッセージを決める際には以下の点に注意しましょう

  • 多言語での使用が見込まれるアプリケーションでは、例外のメッセージもローカライズした文字列を含めること
  • 適切な文法を使用すること

finally句では例外が発生しないようにすべし

finally句で例外が発生すると、アクティブな例外が新しい例外によって隠されてしまいます

それによって、元のエラーの検出およびデバッグが困難になってしまうため、finally句では明示的に例外をスローしないようにしましょう

例外をスローすべきでないメソッドを把握すべし

.NETのコーディングにおいて、例外をスローしないことが前提のメソッドが存在します

以下のタイミングでの明示的なスローは避けましょう

  • プロパティの get メソッド
  • イベント アクセサー メソッド
  • Equals メソッド
  • GetHashCode メソッド
  • ToString メソッド
  • 静的コンストラクター
  • ファイナライザー
  • Dispose メソッド
  • 等値演算子
  • 暗黙的なキャスト演算子

引数検証例外は同期的にスローすべし

async修飾子で宣言されたメソッドでは、スローされた例外は、返されるTaskに格納されるため、タスクが待機されるまで発生しません

非同期メソッドを呼び出すために使用する引数を検証してArgumentExceptionArgumentNullExceptionをスローする場合は、非同期処理実行前に検証しましょう

カスタム例外のベストプラクティス

アプリケーションによっては独自のカスタム例外を実装しなければならないケースもあるでしょう

最後にカスタム例外の実装方法についてまとめていきます

クラス名の末尾にはExceptionをつけるべし

カスタム例外を実装する場合は、Exceptionクラスやその他適切な例外クラスを継承して新しい例外クラスを新規で作成する必要があります

先ほど.NET標準の例外クラスの代表例をいくつか挙げましたが、全てクラス名の末尾に"Exception"とついてますね

例外クラスであることが一目で判断できるように末尾には"Exception"とつけましょう

3つのコンストラクターを含めるべし

独自の例外クラスを実装する際は、他の標準例外クラスと同様の手法で使用できるように以下のコンストラクタを実装しましょう

  • 規定の値を使用するException()
  • 文字列のメッセージを受け取るException(String)
  • 文字列のメッセージと内部例外を受け取るException(Stirng, Exception)

必要に応じてプロパティを追加すべし

プロパティを追加した方が例外としての役割を果たせる場合はカスタムメッセージ文字列以外のプロパティを追加するのもありです

例えば、FileNotFoundExceptionには見つからないファイル名を提供するFileNameというプロパティがあります

ただ、プログラミングの点で追加情報が役立つ場合のみ追加すべきとされているので、追加するか否かはよく検討しましょう

最後に

アプリケーションが落ちなければ良いとただ単にcatchするだけで例外を握りつぶす実装をしていませんか?

正直、私はその場しのぎで例外をとりあえずなんとかする実装をしたことがあります😮‍💨

例外処理を適切に使いこなすことで堅牢なアプリケーションを構築することができます

この記事が例外処理を見つめ直すきっかけになってもらえれば幸いです!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?