web-dev-qa-db-ja.com

スイッチで「goto」を使用しますか?

Never use goto unless in a switch statement fall-throughを読み取る推奨コーディング標準を見てきました。

従わないgotoを正当化する、この「例外」ケースは正確にどのように見えるでしょうか?

47
Brent Arias

C#は、C++の場合のように、(ケースにコードがない場合を除いて)暗黙的にケースを処理することを拒否します:you need include breakexplicitly fall through(または他のケースにジャンプするには)goto caseを使用できます。この動作を取得する方法は他にないため、ほとんどの(賢明な)コーディング標準で許可されています。

switch(variable)
{
case 1:
case 2:
    // do something for 1 and 2
    goto case 3;
case 3:
case 4:
    // do something for 1, 2, 3 and 4
    break;
}

現実的な例(リクエストによる):

switch(typeOfPathName)
{
case "relative":
    pathName = Path.Combine(currentPath, pathName);
    goto case "absolute";

case "expand":
    pathName = Environment.ExpandEnvironmentVariables(pathName);
    goto case "absolute";

case "absolute":
    using (var file = new FileStream(pathName))
    { ... }
    break;

case "registry":
    ...
    break;
}
21
Zooba
   public enum ExitAction {
        Cancel,
        LogAndExit,
        Exit
    }

これはすてきです

ExitAction action = ExitAction.LogAndExit;
switch (action) {
    case ExitAction.Cancel:
        break;
    case ExitAction.LogAndExit:
        Log("Exiting");
        goto case ExitAction.Exit;
    case ExitAction.Exit:
        Quit();
        break;
}

これより(特にQuit()でさらに作業を行う場合)

ExitAction action = ExitAction.LogAndExit;
switch (action) {
    case ExitAction.Cancel:
        break;
    case ExitAction.LogAndExit:
        Log("Exiting");
        Quit();
        break;
    case ExitAction.Exit:
        Quit();
        break;
}
7
djeeg

goto caseの使用に加えて、別のcase句にあるラベルをgotoできます:

    switch(i) {
    case "0":
        // do some stuff
        break;
    case "1":
        // other stuff, then "fall through" to next case clause
        goto Case2;
    case "2":
    Case2:
        break;
    }

これにより、式の値や型を気にせずに別のcase句にジャンプできます。

ただし、breakの代わりに使用できる明示的な「フォールスルー」キーワードはニースだったでしょう...

5
Robert T. Adams

C#がスイッチケースの「フォールスルー」を許可する唯一の方法です。 C#では(C、C++、またはJavaとは異なり)、switchステートメントのcaseブロックは、breakまたはその他の明示的なジャンプステートメントで終了する必要があります。

4
Michael Burr

上記のMehrdad Afshariのアドバイスを拡張することにより、単に「悪いコード」または「悪いコーディング慣行」として構造を追放することを決して勧めません。 「goto」ステートメントでさえ、物事の壮大な計画の中でその場所を持っています。彼らが悪であるという教義は、構造に固有の欠陥のために実現しませんでした-それは、それらが過度に(そして不十分に)過剰に使用されたためでした。

いずれにせよ、カーニハンとリッチーは、訴訟を解決することが適切な方法だと感じました。率直に言って、私はワシントン州レドモンドのどこかで思い浮かぶものよりも、彼らの推論を信頼する傾向があります。または、レドモンドの心の知恵に基づいた教義。

「xxxを使用しない」と聞いた場合は、「原因なし」を付けてください。独断的に何かを捨てることはばかげています。デバイスを作成する理由があるため、デバイスが存在します。後知恵では、通常、「不良」と呼ばれるのは、デバイス自体の障害ではなく、それらを完全に理解していない人々によって不十分に採用されたためです。したがって、デバイスが「不良」になることはほとんどありません。ほとんど常に悪いのは、ユーザー理解です。これは原子核分裂と核融合の場合にも当てはまります。

「goto」ステートメントの使用を避けることが唯一の機能である、ひどくグロテスクなコード構造を見てきました。さらに悪いことは何ですか? 「goto [label]」、または「goto [label]」と入力しなくても済むようにする機能を持つ30行の嫌なコード

教義の前に知識を求めてください。行動する前に考えてください。これらは役に立つアドバイスです。

1
David Wright