まだC#で「goto」キーワード構文を使用している人がいるかどうか、その理由は何ですか。
私は、読者にコードをジャンプさせるようなステートメントを悪い習慣と見なす傾向がありますが、そのような構文を使用するための信頼できるシナリオがあるかどうか疑問に思いましたか?
goto
ループを切断して、特定の条件に応じて文を開始するに戻って
まだC#で「goto」キーワード構文を使用している人がいるかどうか、その理由は何ですか。
私は、読者にコードをジャンプさせるようなステートメントを悪い習慣と見なす傾向がありますが、そのような構文を使用するための信頼できるシナリオがあるかどうか疑問に思いましたか?
goto
ループを切断して、特定の条件に応じて文を開始するに戻って
回答:
gotoが実際に読みやすさを改善できる(まれな)ケースがいくつかあります。実際、リンクしたドキュメントには2つの例がリストされています。
gotoの一般的な用途は、switchステートメントの特定のswitch-caseラベルまたはデフォルトラベルに制御を移すことです。
gotoステートメントは、深くネストされたループから抜け出すのにも役立ちます。
後者の例を次に示します。
for (...) {
for (...) {
...
if (something)
goto end_of_loop;
}
}
end_of_loop:
もちろん、この問題には、コードを関数にリファクタリングする、その周りにダミーブロックを使用するなど、他の方法もあります(詳細については、この質問を参照してください)。補足として、Java言語の設計者はgotoを完全に禁止し、代わりにラベル付きのbreakステートメントを導入することを決定しました。
この部分を覚えています
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;
}
これを参照
gotoは、breakがうまく機能しない多くのループ(エラー条件など)から抜け出すのに最適です。Kragenが言ったように、gotoはコンパイラーがswitch文やその他のことを生成するためにも使用されます。
を使用したことを覚えていませんgoto
。しかし、多分それはあなたが本当に終了したくない永久ループの意図を改善します(いいえbreak
、しかしあなたはまだreturn
またはすることができますthrow
):
forever: {
// ...
goto forever;
}
もう一度、シンプルwhile (true)
で十分です...
goto
。..とwhile(true) {..}
..興味深い使用ではありません
コンパイラはgoto
、生成されたコードのさまざまな部分でステートメントを使用します。たとえば、生成されたイテレータブロックタイプ(yield return
キーワードを使用すると生成されます)-生成されたXMLシリアル化タイプにも、goto
どこかにいくつかのステートメントがあることは確かです。
参照イテレータブロックの実装の詳細を:自動生成されたステートマシンをなぜ/どのようにC#コンパイラハンドルこの上でいくつかの詳細については。
生成されたコード以外にgoto
、通常のコードでステートメントを使用する十分な理由はありません。コードを理解することが難しくなり、結果としてエラーが発生しやすくなります。一方、goto
このように生成されたコードでステートメントを使用すると、生成プロセスが簡略化され、通常は問題ありません。生成されたコードをだれも読み取ったり(または変更したり)したり、マシンが書き込みを行っているためにエラーが発生する可能性がないからです。
古典的なプログラミング履歴だけでなく、反対する議論のために有害であると考えられるGo-toステートメントを参照してくださいgoto
。
goto
ではない。考慮すべきこと。
プロセッサは少なくとも1つのジャンプ命令を実装しており、多くのステートメントがそれらの実装または解釈でそれらを使用していると確信しています。
第3または第4世代の言語を使用することの良い点の1つは、これらの物理的な詳細が抽象化されていることです。漏れやすい抽象化の法則に注意する必要がありますが、ツールも意図したとおりに使用する必要があります(申し訳ありません)。私がコードを書いていてgoto
、それが良い考えのように思われたら、リファクタリングする時がきたでしょう。構造化言語の目的は、これらの「ジャンプ」を回避し、エンジニアリングに論理的なフローを作成することです。
の使用は避けるべきですbreak
が、パフォーマンスの利点を見逃すことはできません。ただし、相互に必要なネストされたループがあるbreak
場合は、リファクタリングする時間です。
誰かがgoto
それを使用することを提案できる場合は、リファクタリングよりも良いようですが、私は喜んで私の答えを取り下げます。
私がここの「自転車置き場」に急いで罪を犯していないことを願っています。クラーゲンが言うように、ダイクストラにとって十分なものは私にとって十分なものです。
dynamic
対象を、私は必要な値にまで取得するには複数の辞書が含まれていることのオブジェクトグラフを歩きます。dynamic
まだ正確なオブジェクトの形状を期待するパラメータを持つメソッドを使用しても意味がありません。gotoを使用して複数のレイヤーを分割し、これらのオブジェクトのコレクションを順に見ていきます。[私はタイプを所有していないので、より良いアクセスを提供できません。そのため、リフレクションまたはダイナミックです]
後藤は決して良くない。続けて、ブレーク(スイッチ/ケースを除く)、(複数回)リターン、スローも最低限に抑える必要があります。ネストループの途中から逃げたくない。ループ制御ステートメントには常にすべてのループ制御が必要です。インデントには情報があり、これらすべてのステートメントはその情報を破棄します。インデントをすべて削除することもできます。