私は時々、開発者が関数にとって重要ではない何かを返すことを選択したメソッドに出くわします。つまり、コードを見ると、明らかにvoid
と同じように機能し、しばらくしてから「なぜですか」と尋ねます。これは聞き覚えがありますか?
たいていの場合、単にbool
を返すのではなく、int
やvoid
のようなものを返す方がよいことに同意する場合があります。しかし、全体像では、長所と短所についてはわかりません。
状況によっては、int
を返すことで、呼び出し元に、メソッドの影響を受ける行またはオブジェクトの量を知らせることができます(たとえば、MSSQLに保存された5つのレコード)。 「InsertSomething」のようなメソッドがブール値を返す場合、成功した場合はtrue
を返し、そうでない場合はfalse
を返すようにメソッドを設計できます。発信者は、その情報に基づいて行動するかどうかを選択できます。
一方、
false
を取得しましたか?または、評価結果が原因でfalseを返しましたか?これであなたの経験は何ですか?これにどのように対処しますか?
メソッドの成功または失敗を示すbool戻り値の場合、.NETメソッドでさまざまに使用されているTry
- prefixパラダイムを好みます。
たとえば、同じキーを持つ行がすでに存在する場合、void InsertRow()
メソッドは例外をスローする可能性があります。問題は、InsertRowを呼び出す前に、呼び出し元が行が一意であることを保証すると想定することは妥当ですか?答えが「いいえ」の場合、行がすでに存在する場合にfalseを返すbool TryInsertRow()
も提供します。 db接続エラーなどの他の場合でも、db接続の維持が呼び出し側の責任であると想定すると、TryInsertRowは例外をスローする可能性があります。
IMHOが「ステータスコード」を返すのは、C#などの中〜高レベルの言語で例外が一般的になる前の歴史的な時代に由来します。現在、予期しないエラーによってメソッドが成功しなかった場合は、例外をスローすることをお勧めします。そうすることで、エラーが気付かれないようにし、呼び出し元が適切に対処できるようにします。したがって、これらのケースでは、ブールステータスフラグまたは整数ステータスコードの代わりにメソッドが何も返さなくても問題ありません(つまり、void
)。 (もちろん、メソッドがスローする可能性のある例外とそのタイミングを文書化する必要があります。)
一方、厳密な意味での関数である場合、つまり、入力パラメーターに基づいて何らかの計算を実行し、その計算の結果を返すことが期待される場合、戻り値の型は明らかです。
1つmayが呼び出し側に役立つと思われる場合、メソッドから「追加」情報を返すことを決定すると、2つの間に灰色の領域があります。挿入で影響を受ける行の数に関する例のように。または、メソッドが要素を連想コレクションに入れる場合、そのキーに関連付けられている以前の値がある場合は、それを返すと便利な場合があります。このような用途は、APIの(既知で予期されている)使用シナリオを注意深く分析することで識別できます。
ピーターの答えは例外をうまくカバーしています。ここでのその他の考慮事項には、 コマンドとクエリの分離 が含まれます。
CQSの原則によると、メソッドはコマンドまたはクエリのいずれかであり、両方ではない必要があります。コマンドは決して値を返さず、状態のみを変更し、クエリは状態のみを返し、状態を変更しないでください。これにより、セマンティクスが非常に明確になり、コードがより読みやすく、保守しやすくなります。
CQSの原則に違反しているケースがいくつかありますが、これは良い考えです。これらは通常、パフォーマンスまたはスレッドセーフティに関連しています。
道が何であれ、これであなたは歩くつもりです。今後の使用のために戻り値をそこに入れないでください(たとえば、関数が常にtrueを返すようにします)。これは多大な労力の無駄であり、コードを読みやすくしません。戻り値がある場合は常にそれを使用する必要があり、それを使用できるようにするには、少なくとも2つの可能な戻り値が必要です。
以前はたくさんのvoid関数を書いていました。しかし、メソッドチェーン全体の亀裂に乗ったので、私はvoidではなくこれを返すようになりました-誰かが戻りを利用して、voidでしゃがむことができないようにすることもできます。そして、彼らがそれで何もしたくないなら、彼らはそれを無視することができます。