4

私は大規模なコード レビューを行ってきましたが、いたるところで気づいた 1 つのパターンは次のとおりです。

public bool MethodName()
{
    bool returnValue = false;
    if (expression)
    {
        // do something
        returnValue = MethodCall();
    }
    else
    {
        // do something else
        returnValue = Expression;
    }

    return returnValue;
}

これは、私がこれを行う方法ではなく、それが何であるかを知っていたときに値を返すだけでした。この2つのパターンのうち、どちらがより正しいでしょうか?

戻り値が 1 つのプレーブにのみ割り当てられ、割り当てられた後にコードが実行されないように、ロジックが常に構造化されているように見えることを強調します。

4

12 に答える 12

3

多くの人は、メソッドからの出口点を1つだけにすることを推奨しています。上記で説明したパターンは、その推奨事項に従います。

その推奨事項の主な要点は、メソッドから戻る前にメモリまたは状態をクリーンアップする必要がある場合は、そのコードを1か所にのみ配置することをお勧めします。複数の出口ポイントがあると、クリーンアップコードが重複するか、1つ以上の出口ポイントでクリーンアップコードが欠落しているために問題が発生する可能性があります。

もちろん、メソッドが数行の長さである場合、またはクリーンアップが必要ない場合は、複数のリターンが得られる可能性があります。

于 2008-09-26T14:15:14.527 に答える
2

私は少数派になると思いますが、例に示されているスタイルが好きです。ログステートメントを追加し、ブレークポイントIMOを設定するのは簡単です。さらに、一貫した方法で使用すると、複数のリターンを持つよりも「パターンマッチ」する方が簡単なようです。

ただし、これについて「正しい」答えがあるかどうかはわかりません。

于 2008-09-26T14:13:16.327 に答える
2

制御構造を減らすために、三項を使用していたでしょう...


return expression ? MethodCall() : Expression;

于 2008-09-26T14:11:24.597 に答える
1

一部の学習機関や本は、シングルリターンの実践を提唱しています。

それが良いかどうかは主観的です。

于 2008-09-26T14:12:48.043 に答える
1

それは悪いOOP設計の一部のように見えます。おそらく、単一のメソッド内よりも高いレベルでリファクタリングする必要があります。

それ以外の場合は、次のような3項演算子を使用することをお勧めします。

return expression ? MethodCall() : Expression;

短くて読みやすくなっています。

于 2008-09-26T14:16:01.060 に答える
1

次のいずれかの状況では、メソッドからすぐに戻ります。

  1. 境界条件が見つかり、一意の値またはセンチネル値を返す必要がある場合:if (node.next = null) return NO_VALUE_FOUND;
  2. 必要な値/状態が false であるため、メソッドの残りの部分は適用されません (別名ガード句)。例えば:if (listeners == null) return null;
  3. メソッドの目的は、特定の値を見つけて返すことです。if (nodes[i].value == searchValue) return i;
  4. メソッドの他の場所で使用されていないメソッドから一意の値を返す句にいます。if (userNameFromDb.equals(SUPER_USER)) return getSuperUserAccount();

それ以外の場合は、return ステートメントを 1 つだけにすると便利です。これにより、デバッグ ログの追加、リソースのクリーンアップ、ロジックの追跡が容易になります。上記の 4 つのケースすべてを最初に処理し、該当する場合は、result(s)できるだけ遅い名前の変数を宣言し、必要に応じて値を割り当てます。

于 2008-10-20T05:35:44.620 に答える
0

それらは両方とも同じタスクを実行します。メソッドには、1つの入口と1つの出口点のみが必要であると言う人もいます。

于 2008-09-26T14:12:39.603 に答える
0

私もこれを使っています。アイデアは、プログラムの通常のフローでリソースを解放できるということです。20の異なる場所でメソッドから飛び出し、前にcleanUp()を呼び出す必要がある場合は、さらに別のクリーンアップメソッドを20回追加する(またはすべてをリファクタリングする)必要があります。

于 2008-09-26T14:12:52.223 に答える
0

コーダーは、メソッドの先頭にオブジェクトtoReturnを定義し(たとえば、List <Foo> toReturn = new ArrayList <Foo>();)、メソッド呼び出し中にそれを入力するという設計を採用していると思います。奇妙なブールリターン型に適用します。

また、メソッド本体の途中では戻ることができず、最後にのみ戻ることができるというコーディング標準の副作用である可能性もあります。

于 2008-09-26T14:13:53.483 に答える
0

戻り値が割り当てられた後にコードが実行されなくても、後でコードを追加する必要がないという意味ではありません。

これは使用できる最小のコードではありませんが、リファクタリングに非常に適しています。

于 2008-09-26T14:14:42.080 に答える
0

Delphiは、関数の戻り型となる「Result」という変数を自動的に作成することにより、このパターンを強制します。関数が終了したときの「結果」が何であれ、戻り値です。したがって、「return」キーワードはまったくありません。

function MethodName : boolean;
begin
  Result := False;
  if Expression then begin
    //do something
    Result := MethodCall;
  end
  else begin
    //do something else
    Result := Expression;
  end;

  //possibly more code
end;
于 2008-09-26T14:17:01.060 に答える
0

使用されるパターンは冗長ですが、[レジスタ] ウィンドウを開いて EAX をチェックせずに戻り値を知りたい場合は、デバッグも簡単です。

于 2008-09-26T14:39:32.143 に答える