私はこれについて私が言いたいことを知っていると思いますが、よくわかりません...
フレームワークのドキュメントでは、型を次のように要約しています。
メソッド呼び出しがオブジェクトの現在の状態に対して無効である場合にスローされる例外。
明確なケースがあり、思いつくのは、操作でデータベースを開く必要があるが、データベースに接続するために必要な情報でオブジェクトが初期化されていない場合です。
(接線: 一方、接続を明示的に開くことも要求する ADO.NET の動作は明確ではありません。DataAdapter は、単に接続を代わりに開き、接続が閉じられた場合にのみ再度閉じることによって、これから逸脱します。エントリ, そして私はこれが便利だと思い、すべてのためにこのパターンを使用するADO.NETラッパーを自分自身にしました. もちろん、これは2つのExecuteNonQueryを実行し、その間に不必要にプールへの接続を返すリスクがあることを意味します, しかし、私はまだ開いたり閉じたりすることができます私が望むときに接続し、このパフォーマンスの低下は、例外を取得することに比べれば何もありません.)
私の質問に対する答えは、そのような明確な状況でのみ例外をスローする必要があるということだと思います。ただし、次のシナリオでは、どの例外の種類が最も適切でしょうか。
public class FormatterMapping
{
Dictionary formattersByName = new ...();
public IFormatter GetFormatter(string key)
{
IFormatter f;
if (formattersByName.TryGetValue(key, out f))
return f;
else
throw new ??Exception("explanation of why this failed.");
}
}
私の最初の本能は、ArgumentException をスローすることでした。それから、引数が「間違っている」のと同じように、マッピングにキーが欠落している可能性があると考え始めました。X がマッピングに含まれていないため、基本的に「Get formatter X」操作は無効ですが、X が「そこにあるはずだった」のか、ここで X を要求するのが賢明ではないのか、私にはまったくわかりません。
もちろん、null を返すことで問題全体を回避することもできますが、それはより大きく、より深いワームの缶を開きます。戻り値がいつ使用されるかを知る方法がないため、NullReferenceException で後で爆発するコードは、問題が発生した場所と明確な関係を持っていない可能性があります。マッピングが正しく設定されていないか、それを使用するコードが要求してはならないものを要求したかのいずれかです。
この問題を回避する別の方法は、TryGetFormatter オプションを使用することですが、これを使用する方法は、呼び出し元がマッピングに含まれるものと含まれないものを実際に認識しているため、ユーザー コードにこのパターンを強制することはできません。どちらでもいいです。
答えないでください。ApplicationException をスローする必要があります。そして、コードが何をすべきだと思うかについて、その理由を提供してください。結局のところ、ここで本当に問題になっているのは推論です。
誰かが私を別の方法で説得するまで、私は ArgumentException に傾いています。マッピングの観点からは、この議論は間違っているので、少なくともこれを裏付ける明確な理由が 1 つあります。:)