C#で "goto"キーワード構文をまだ使用している人がいるのか、そうする理由として考えられるものは何かと思いまして。
私は読者にコードを飛び回らせるような文を悪い習慣と見なす傾向がありますが、そのような構文を使用するための信頼できるシナリオがあるかどうか疑問に思いましたか?
Gotoが実際に読みやすさを改善できる(まれな)ケースがいくつかあります。実際、リンクしたドキュメントには2つの例がリストされています。
Gotoの一般的な使用法は、switchステートメントの特定のswitch-caseラベルまたはデフォルトラベルに制御を移すことです。
Gotoステートメントは、深くネストされたループから抜け出すのにも役立ちます。
後者の例を次に示します。
for (...) {
for (...) {
...
if (something)
goto end_of_loop;
}
}
end_of_loop:
もちろん、この問題を回避する方法は他にもあります。たとえば、コードを関数にリファクタリングする、ダミーブロックを使用するなどです(詳細については this question を参照してください)。補足説明として、Java言語設計者はgoto)を完全に禁止し、ラベル付きブレークを導入することを決定しました代わりにステートメント。
この部分を覚えている
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;
}
参照 これ
Eduasync で広範囲に使用して、C#5で非同期メソッドを使用するときにコンパイラーが生成するコードの種類を示します。イテレーターブロックでも同じことがわかります。
「通常の」コードでは、前回使用したことを思い出せません...
gotoは、ブレークがうまく機能しない多くのループ(エラー状態など)から抜け出すのに最適であり、Krgenが言ったように、gotoはコンパイラーによってswitchステートメントなどを生成するためにも使用されます。
goto
を使用したことを覚えていません。しかし、maybeこれは、本当に終了したくない永久ループの意図を改善します(break
はありませんが、return
またはthrow
):
_forever: {
// ...
goto forever;
}
_
もう一度、単純なwhile (true)
で十分です...
また、couldは、ループの最初の繰り返しをループの途中で開始したい状況で使用します:look here 例。
コンパイラーは、生成されたさまざまなコードでgoto
ステートメントを使用します。たとえば、生成されたイテレーターブロックタイプ(yield return
キーワード-生成されたXMLシリアル化タイプには、いくつかのgoto
ステートメントもどこかにあると確信しています。
C#コンパイラがこれを処理する理由/方法の詳細については、 イテレータブロックの実装の詳細:自動生成されたステートマシン を参照してください。
生成されたコード以外に、通常のコードでgoto
ステートメントを使用する正当な理由はありません。コードが理解しにくくなり、結果としてエラーが発生しやすくなります。一方、このような生成されたコードでgoto
ステートメントを使用すると、生成プロセスを簡素化でき、通常は問題ありません。マシンが書き込みを行っています。
goto
に対する引数およびプログラミング履歴の古典的な部分については、 有害と見なされるGo-toステートメント を参照してください。
プロセッサは少なくとも1つの jump instruction を実装しており、多くのステートメントがそれらの実装または解釈で使用されていると確信しています。
rd または 4th 生成言語を使用することの良い点の1つは、これらの物理的な詳細が抽象化されていることです。 漏れやすい抽象化の法則 に留意する必要がありますが、 意図したとおりのツール (ごめんなさい)。コードを書いていて、goto
が良いアイデアのように思えたら、リファクタリングする時が来たでしょう。構造化言語の目的は、これらの「ジャンプ」を回避し、エンジニアリングの論理フローを作成することです。
break
の使用を避ける必要がありますが、パフォーマンス上のメリットを見逃すことはできません。ただし、相互にbreak
を必要とするネストされたループがある場合は、リファクタリングを行います。
誰かがリファクタリングよりも良いと思われるgoto
の使用を提案できる場合、私は喜んで私の回答を撤回します。
ここで「 bike shed 」に急いで罪を犯さないことを願っています。 Kragenが言うように、 Dijkstra に十分なもので十分です。