私はクラスを持っています:
class Foo
{
public Foo(string bar)
{
if (string.IsNullOrEmpty(bar))
throw new Exception("bar must not be null or empty.");
}
}
スローする最も正しい例外タイプは何ですか?
実行可能な候補者は次のとおりです。
ArgumentNullException
ArgumentException
InvalidOperationException
TypeInitializationException
私の本能はInvalidOperationException
にもメリットがありますが、呼び出し元が不正な状態でオブジェクトを構築しようとしているため、ArgumentException
を使用することです。
StringNullOrEmptyException
があったらいいのにと思いませんか。
編集提案された質問に感謝します。これは似ていますが、コンストラクターで発生する問題と、それが推奨事項を変更するかどうかについて具体的に尋ねていました。
私は最も正しい実装がこれだと思います:
if (bar == null) { throw new ArgumentNullException (...); }
else if (bar.Trim() == "") { throw new ArgumentException (...); }
しかし、私たちはブヨを緊張させ、ラクダを飲み込むかもしれません。それはおそらくそれほど重要ではありません。
一方、 StringNullOrEmptyException
クラスを作成することもできます。
このような状況を処理する非常に一般的な方法の1つは、2つの異なる例外をスローすることです。1つはnull
に対するもので、もう1つは無効な非null文字列に対するものです。
if (bar == null) {
throw new ArgumentNullException("bar");
}
if (string.IsNullOrWhiteSpace(bar)) {
throw new ArgumentException("bar");
}
他の例外についても触れたので、以下にそれらの意味を示します。
ArgumentNullException
-問題の引数がnull
であることを示しますArgumentException
-問題の引数がnullではないが、それ以外の場合は無効であることを示します。InvalidOperationException
-オブジェクトの現在の状態では操作を実行できないことを示します。TypeInitializationException
-タイプ(タイプのインスタンスではなく、タイプ自体)を初期化できないことを示します。このリストの最初の3つの例外は、常に呼び出し側のプログラミングの問題を示しています。つまり、受け取った呼び出し側は、APIを誤って呼び出しているため、コードを修正する必要があることを認識しています。
最後の例外は、プログラミングの問題を示しています。つまり、このエラーを受け取った発信者は、エラーを修正するか、ライブラリをインストールする方法を再構成するためにあなたを呼び出す必要があることを知っています。
ArgumentException
は、次の理由でここで最も意味があります
ArgumentNullException
->文字列が空である可能性があるため無効ですInvalidOperationException
->失敗している操作ではなく、コンストラクターの引数です本当にStringNullOrEmptyException
が本当に必要な場合は、自分で作成できますが、ほとんどの場合、システム定義の例外に固執する必要があることに同意する傾向があります。