web-dev-qa-db-ja.com

いつ、なぜ(例えばbool / intの代わりに)voidを使うべきか

私は時々、開発者が関数にとって重要ではない何かを返すことを選択したメソッドに出くわします。つまり、コードを見ると、明らかにvoidと同じように機能し、しばらくしてから「なぜですか」と尋ねます。これは聞き覚えがありますか?

たいていの場合、単にboolを返すのではなく、intvoidのようなものを返す方がよいことに同意する場合があります。しかし、全体像では、長所と短所についてはわかりません。

状況によっては、intを返すことで、呼び出し元に、メソッドの影響を受ける行またはオブジェクトの量を知らせることができます(たとえば、MSSQLに保存された5つのレコード)。 「InsertSomething」のようなメソッドがブール値を返す場合、成功した場合はtrueを返し、そうでない場合はfalseを返すようにメソッドを設計できます。発信者は、その情報に基づいて行動するかどうかを選択できます。

一方、

  • メソッド呼び出しの目的が明確になりませんか?悪いコーディングはしばしば私にメソッドの内容を再確認させます。それが何かを返す場合、それはメソッドがタイプhaveであり、返された結果で何かを行うことを示します。
  • もう1つの問題は、メソッドの実装が不明な場合、開発者は何が機能的に重要ではないものを返すことを決定したでしょうか。もちろんコメントできます。
  • メソッドの閉じ括弧で処理を終了できる場合は、戻り値を処理する必要があります。
  • フードの下で何が起こりますか?スローされたエラーが原因で、呼び出されたメソッドがfalseを取得しましたか?または、評価結果が原因でfalseを返しましたか?

これであなたの経験は何ですか?これにどのように対処しますか?

30
Independent

メソッドの成功または失敗を示すbool戻り値の場合、.NETメソッドでさまざまに使用されているTry- prefixパラダイムを好みます。

たとえば、同じキーを持つ行がすでに存在する場合、void InsertRow()メソッドは例外をスローする可能性があります。問題は、InsertRowを呼び出す前に、呼び出し元が行が一意であることを保証すると想定することは妥当ですか?答えが「いいえ」の場合、行がすでに存在する場合にfalseを返すbool TryInsertRow()も提供します。 db接続エラーなどの他の場合でも、db接続の維持が呼び出し側の責任であると想定すると、TryInsertRowは例外をスローする可能性があります。

32
Bubblewrap

IMHOが「ステータスコード」を返すのは、C#などの中〜高レベルの言語で例外が一般的になる前の歴史的な時代に由来します。現在、予期しないエラーによってメソッドが成功しなかった場合は、例外をスローすることをお勧めします。そうすることで、エラーが気付かれないようにし、呼び出し元が適切に対処できるようにします。したがって、これらのケースでは、ブールステータスフラグまたは整数ステータスコードの代わりにメソッドが何も返さなくても問題ありません(つまり、void)。 (もちろん、メソッドがスローする可能性のある例外とそのタイミングを文書化する必要があります。)

一方、厳密な意味での関数である場合、つまり、入力パラメーターに基づいて何らかの計算を実行し、その計算の結果を返すことが期待される場合、戻り値の型は明らかです。

1つmayが呼び出し側に役立つと思われる場合、メソッドから「追加」情報を返すことを決定すると、2つの間に灰色の領域があります。挿入で影響を受ける行の数に関する例のように。または、メソッドが要素を連想コレクションに入れる場合、そのキーに関連付けられている以前の値がある場合は、それを返すと便利な場合があります。このような用途は、APIの(既知で予期されている)使用シナリオを注意深く分析することで識別できます。

28
Péter Török

ピーターの答えは例外をうまくカバーしています。ここでのその他の考慮事項には、 コマンドとクエリの分離 が含まれます。

CQSの原則によると、メソッドはコマンドまたはクエリのいずれかであり、両方ではない必要があります。コマンドは決して値を返さず、状態のみを変更し、クエリは状態のみを返し、状態を変更しないでください。これにより、セマンティクスが非常に明確になり、コードがより読みやすく、保守しやすくなります。

CQSの原則に違反しているケースがいくつかありますが、これは良い考えです。これらは通常、パフォーマンスまたはスレッドセーフティに関連しています。

14
Andy Lowry

道が何であれ、これであなたは歩くつもりです。今後の使用のために戻り値をそこに入れないでください(たとえば、関数が常にtrueを返すようにします)。これは多大な労力の無駄であり、コードを読みやすくしません。戻り値がある場合は常にそれを使用する必要があり、それを使用できるようにするには、少なくとも2つの可能な戻り値が必要です。

3
refro

以前はたくさんのvoid関数を書いていました。しかし、メソッドチェーン全体の亀裂に乗ったので、私はvoidではなくこれを返すようになりました-誰かが戻りを利用して、voidでしゃがむことができないようにすることもできます。そして、彼らがそれで何もしたくないなら、彼らはそれを無視することができます。

1
Wyatt Barnett