web-dev-qa-db-ja.com

コンストラクターに渡される空のnull文字列の例外を修正

私はクラスを持っています:

class Foo
{
    public Foo(string bar)
    {
        if (string.IsNullOrEmpty(bar))
            throw new Exception("bar must not be null or empty.");
    }
}

スローする最も正しい例外タイプは何ですか?

実行可能な候補者は次のとおりです。

  1. ArgumentNullException
  2. ArgumentException
  3. InvalidOperationException
  4. TypeInitializationException (以下のdasblinkenlightのようにこれではありません)

私の本能はInvalidOperationExceptionにもメリットがありますが、呼び出し元が不正な状態でオブジェクトを構築しようとしているため、ArgumentExceptionを使用することです。

StringNullOrEmptyExceptionがあったらいいのにと思いませんか。

編集提案された質問に感謝します。これは似ていますが、コンストラクターで発生する問題と、それが推奨事項を変更するかどうかについて具体的に尋ねていました。

17
BanksySan

私は最も正しい実装がこれだと思います:

if (bar == null) { throw new ArgumentNullException (...); }
else if (bar.Trim() == "") { throw new ArgumentException (...); }

しかし、私たちはブヨを緊張させ、ラクダを飲み込むかもしれません。それはおそらくそれほど重要ではありません。

一方、 StringNullOrEmptyException クラスを作成することもできます。

15
Mike Perrenoud

このような状況を処理する非常に一般的な方法の1つは、2つの異なる例外をスローすることです。1つはnullに対するもので、もう1つは無効な非null文字列に対するものです。

if (bar == null) {
    throw new ArgumentNullException("bar");
}
if (string.IsNullOrWhiteSpace(bar)) {
    throw new ArgumentException("bar");
}

他の例外についても触れたので、以下にそれらの意味を示します。

  1. ArgumentNullException-問題の引数がnullであることを示します
  2. ArgumentException-問題の引数がnullではないが、それ以外の場合は無効であることを示します。
  3. InvalidOperationException-オブジェクトの現在の状態では操作を実行できないことを示します。
  4. TypeInitializationException-タイプ(タイプのインスタンスではなく、タイプ自体)を初期化できないことを示します。

このリストの最初の3つの例外は、常に呼び出し側のプログラミングの問題を示しています。つまり、受け取った呼び出し側は、APIを誤って呼び出しているため、コードを修正する必要があることを認識しています。

最後の例外は、プログラミングの問題を示しています。つまり、このエラーを受け取った発信者は、エラーを修正するか、ライブラリをインストールする方法を再構成するためにあなたを呼び出す必要があることを知っています。

13
dasblinkenlight

ArgumentExceptionは、次の理由でここで最も意味があります

  • ArgumentNullException->文字列が空である可能性があるため無効です
  • InvalidOperationException->失敗している操作ではなく、コンストラクターの引数です

本当にStringNullOrEmptyExceptionが本当に必要な場合は、自分で作成できますが、ほとんどの場合、システム定義の例外に固執する必要があることに同意する傾向があります。

8