楽で正しいArgumentOutOfRangeExceptionの使い方はこれだ!
もちろん `ArgumentOutOfRangeException` を使うのがふさわしい場面であることが前提です。
最初に結論から。続く最悪な例も見てください。
😊こうしましょう
以下の paramName は実際の引数名に変えてください。
😊VB.NET の場合
Throw New ArgumentOutOfRangeException(NameOf(paramName), paramName, Nothing)
😊C# なら
throw new ArgumentOutOfRangeException(nameof(paramName), paramName, null)
サンプルコード (VB.NET)
以下の例では、実際の引数名である `temperature` を `NameOf` に渡しています。12行目をご覧ください。
😡だめな例
第3引数に空の文字列 "" を渡すのは最悪です。
😡VB.NET の場合
Throw New ArgumentOutOfRangeException(NameOf(paramName), paramName, "")
😡C# なら
throw new ArgumentOutOfRangeException(nameof(paramName), paramName, "")
説明
例外オブジェクトは開発者のために十分な情報を持つ必要があります。とはいえ、めんどくさいことはしたくない。メッセージを自分で考えるのはめんどくさいよね。メッセージのローカライズまで考えるなんてもう嫌だ……。
そこで、楽で正しいコスパの良い方法が求められるわけです。バランス感。
どんな情報があればうれしいか
せっかく引数がらみの例外なんだから「引数名」は知りたいよね。
Out Of Range なんだけど、範囲外の値って実際どうだったんだろう?というわけで「実際の値」も欲しい。
とはいえ自分でメッセージを考えたり組み立てたりはしたくない…。
これらを満たすのが「😊こうしましょう」の方法です。
なぜ第3引数に空の文字列 "" を渡すのは最悪なのか
わざわざ引数を渡す苦労をしているのに、得られる情報が落ちてしまうからです。メッセージに型名が含まれなくなります。
Visual Studio などのデバッグ中であれば例外の型は分かりますが、それでも型名がメッセージに含まれた方がうれしいですし、コンソールやログだと型名が出力されなくなるのはよくありません。
実は ArgumentOutOfRangeException に限った話ではなく、Exception とその派生クラスは message 引数に空の文字列 "" を渡すと同じことが起きます。
なので、コンストラクタの message 引数には Nothing/null を渡すか、message 引数無しバージョンを使うのが常にベターとなります。
Messsageプロパティの違い
😊Nothing/null バージョン
message 引数にNothing/nullを渡した場合、デフォルトのメッセージで型名が表示されます。
Exception of type 'System.ArgumentOutOfRangeException' was thrown. (Parameter 'temperature')
Actual value was 60.
😡空の文字列 "" バージョン
message 引数に空の文字列 "" を渡した場合、型名が表示されるデフォルトのメッセージを空の文字列で上書きしてぶち壊してしまいます。
(Parameter 'temperature')
Actual value was 60.
まとめ
ArgumentOutOfRangeException には、「引数名」と「実際の引数」と Nothing/null を渡しましょう。
そうすることで、Messageで「型名」と「引数名」と「実際の引数」を得られます。
デフォルトのメッセージで「型名」が出力されるのでそのまま楽して使っちゃいましょう。
メッセージに空の文字列 "" を渡してデフォルトのメッセージをぶち壊さないようにしましょう。Nothing/null を渡すことでデフォルトのメッセージを生かしましょう。