web-dev-qa-db-ja.com

誰でもC#で[goto]を使用していますか?

C#で "goto"キーワード構文をまだ使用している人がいるのか、そうする理由として考えられるものは何かと思いまして。

私は読者にコードを飛び回らせるような文を悪い習慣と見なす傾向がありますが、そのような構文を使用するための信頼できるシナリオがあるかどうか疑問に思いましたか?

後藤キーワード定義

95
Brian Scott

Gotoが実際に読みやすさを改善できる(まれな)ケースがいくつかあります。実際、リンクしたドキュメントには2つの例がリストされています。

Gotoの一般的な使用法は、switchステートメントの特定のswitch-caseラベルまたはデフォルトラベルに制御を移すことです。

Gotoステートメントは、深くネストされたループから抜け出すのにも役立ちます。

後者の例を次に示します。

for (...) {
    for (...) {
        ...
        if (something)
            goto end_of_loop;
    }
}

end_of_loop:

もちろん、この問題を回避する方法は他にもあります。たとえば、コードを関数にリファクタリングする、ダミーブロックを使用するなどです(詳細については this question を参照してください)。補足説明として、Java言語設計者はgoto)を完全に禁止し、ラベル付きブレークを導入することを決定しました代わりにステートメント。

86
Heinzi

この部分を覚えている

switch (a)     
{ 
    case 3: 
        b = 7;
        // We want to drop through into case 4, but C# doesn't let us
    case 4: 
        c = 3;
        break; 
    default: 
        b = 2;
        c = 4;
        break; 
}

このようなものに

switch (a)     
{
    case 3: 
        b = 7;
        goto case 4;    
    case 4: 
        c = 3;
        break;     
    default: 
        b = 2;
        c = 4;
        break;
}

参照 これ

62
V4Vendetta

Eduasync で広範囲に使用して、C#5で非同期メソッドを使用するときにコンパイラーが生成するコードの種類を示します。イテレーターブロックでも同じことがわかります。

「通常の」コードでは、前回使用したことを思い出せません...

22
Jon Skeet

gotoは、ブレークがうまく機能しない多くのループ(エラー状態など)から抜け出すのに最適であり、Krgenが言ったように、gotoはコンパイラーによってswitchステートメントなどを生成するためにも使用されます。

8
Jesus Ramos

gotoを使用したことを覚えていません。しかし、maybeこれは、本当に終了したくない永久ループの意図を改善します(breakはありませんが、returnまたはthrow):

_forever: {
  // ...
  goto forever;
}
_

もう一度、単純なwhile (true)で十分です...

また、couldは、ループの最初の繰り返しをループの途中で開始したい状況で使用します:look here 例。

6
Jordão

コンパイラーは、生成されたさまざまなコードでgotoステートメントを使用します。たとえば、生成されたイテレーターブロックタイプ(yield returnキーワード-生成されたXMLシリアル化タイプには、いくつかのgotoステートメントもどこかにあると確信しています。

C#コンパイラがこれを処理する理由/方法の詳細については、 イテレータブロックの実装の詳細:自動生成されたステートマシン を参照してください。

生成されたコード以外に、通常のコードでgotoステートメントを使用する正当な理由はありません。コードが理解しにくくなり、結果としてエラーが発生しやすくなります。一方、このような生成されたコードでgotoステートメントを使用すると、生成プロセスを簡素化でき、通常は問題ありません。マシンが書き込みを行っています。

gotoに対する引数およびプログラミング履歴の古典的な部分については、 有害と見なされるGo-toステ​​ートメント を参照してください。

5
Justin

プロセッサは少なくとも1つの jump instruction を実装しており、多くのステートメントがそれらの実装または解釈で使用されていると確信しています。

rd または 4th 生成言語を使用することの良い点の1つは、これらの物理的な詳細が抽象化されていることです。 漏れやすい抽象化の法則 に留意する必要がありますが、 意図したとおりのツールごめんなさい)。コードを書いていて、gotoが良いアイデアのように思えたら、リファクタリングする時が来たでしょう。構造化言語の目的は、これらの「ジャンプ」を回避し、エンジニアリングの論理フローを作成することです。

breakの使用を避ける必要がありますが、パフォーマンス上のメリットを見逃すことはできません。ただし、相互にbreakを必要とするネストされたループがある場合は、リファクタリングを行います。

誰かがリファクタリングよりも良いと思われるgotoの使用を提案できる場合、私は喜んで私の回答を撤回します。

ここで「 bike shed 」に急いで罪を犯さないことを願っています。 Kragenが言うように、 Dijkstra に十分なもので十分です。

2
Jodrell