4

switchこれは特にC#の質問ではありませんが、私が質問するのはC#バージョンです。

caseフォールスルーしたい場合を示す代わりに、あるステートメントから次のステートメントにフォールスルーしたくないことを明示的に述べる必要があるのはなぜですか?

C# では、コンパイラはcase(ステートメントが空の場合を除いて) あるステートメントから次のステートメントに移行することを許可しませんが、すべてのステートメントの最後にcase明示的に配置することを強制します。私が書いたステートメントbreakの大部分は失敗しません。switch

int x = 4;
string result;

switch (x)
{
case 1:
   result = "One";
   break;
case 2:
   result = "A couple";
   break;
case 3:
case 4:
   result = "Three or four";
   break;
/*
case 5:
   result = "Five";   // Here be an error! A common typo for me!!!
*/
default:
   result = "Five or more";
   break;
}

上記の例は、可能性を示すために工夫されています。実際に失敗する回数 (上記の 3 から 4 の間など) は最小限です。上記のケース 5 からコメントを削除すると、C# コンパイラはそれをエラーとしてキャッチします。コンパイラが私がやろうとしていることを完全に知っているのに、なぜ手動で修正しなければならないのですか?

以下の方が良いのではないでしょうか?

int x = 4;
string result;

switch (x)
{
case 1:
   result = "One";
case 2:
   result = "A couple";
case 3:
   continue;   // or even goto 4
case 4:
   result = "Three or four";
/*
case 5:
   result = "Five";   // This would not longer be an error!! Hooray!
*/
default:
   result = "Five or more";
}

ここでフォールスルーを主張しているわけではないことを明確にさせてください. breakすべてのcaseステートメントの最後に暗黙があります。2 つの例は、機能的に同等であることを意図しています。

ケース 3のステートメントを忘れた場合でも、コンパイラは私に怒鳴る可能性がcontinueあります。実際、このケースでは、スケルトン コードを埋め損ねた可能性が非常に高いです。使える。ステートメントを忘れたと私に言うことbreakは決して役に立ちません。コンパイラを満足させるのは、もっと忙しい仕事です。

これはおそらくCからのホールドオーバーに過ぎないようです(caseステートメントにコードがある場合でも、失敗する可能性があります)。私が見えないもっと深い理由がありますか?

今朝、いくつかのコンパイラ コードを見ていましたが、オペレーション コードを返すだけのcaseステートメントが aに何百もありました。switchそれぞれに発表がありましたbreak。たくさんのタイピングと混乱...

人々はどう思いますか?2 番目のオプションがより適切なデフォルトではないのはなぜですか?

4

3 に答える 3

6

C# ステートメントの論理的根拠は、C の動作は、 、、またはswitchのようなステートメントで明示的に終了しない限り、ケースが失敗するということです。これは、C に精通しているすべての人 (おそらくほとんどの C# プログラマー) は、C#構文がほぼ同じことを意味することを期待することを意味します。C# の設計者が失敗しないように作成した場合、コードはユーザーの期待とは正反対の動作をするでしょう!breakreturngotoswitch

一方でbreak、ケースの最後にあるステートメントを忘れて、本来あるべきではないところにコントロールが落ちてしまうことは、バグの一般的な原因です。あまり一般的でない問題は、人々がケースの順序を変更して、以前は最後にあった (そして を必要としないbreak) ケースが最後になくなる (そして予期せず失敗する) ことです。

言い換えれば、ケースが失敗しないようにすると、失敗することを期待している人々からバグが発生しますが、ケースの明示的な終了を要求しないと、break. したがって、ケースが失敗することはありませんが、 abreakは依然として必要です。

于 2011-08-09T01:25:21.803 に答える
1

switch ステートメントは、このようなことが起こった場合に本当に役立ちます (ifs を置き換えるため)。

switch (my_var) {
    case 1:
    case 2:
    case 3:
    case 4:
        do_something();
        break;
    case 5:
    case 6:
    case 7:
    case 8:
        do_something else();
        break;
}

これにより、ネストされた if や、and を含む巨大な if ステートメントが大幅に置き換えられます。

もう 1 つの主な理由は、C から持ち帰ったようなものだということです。Case ステートメントは、コンパイラによって生成されるアセンブリとほぼ同じように見えます (場合によっては)。なぜ彼らが最初にこの設計を採用したのかはあまりよくわかりませんが、同じ数の if が散らかっているように見えるかもしれないので、実際には問題はありません (常にではありません)。

C# はおそらく、欠落しているブレークをエラーとして認識し (一般的なものです)、おそらくそれがフラグを立てる理由です。通常、これはデフォルトステートメントにフォールスルーする最後のステートメントでのみ行われ、デフォルトステートメント自体にはブレークが必要です (いつでもデフォルトを先頭に置くことができるため)。C# は、すべてのケース (またはいくつかのケース) の最後に break を入力するのを忘れて実行に失敗することによって発生する単純なバグを回避するために、この意味で厳密にしようとします。

于 2011-08-09T00:46:15.397 に答える
0

CとC++に暗黙のフォールスルーがある理由は、まれではありますが、それに依存する膨大な量のコードとの下位互換性です。

C#に暗黙のフォールスルーがない理由は、ほとんどの場合、バグであるためです。C#に暗黙のブレークがない理由は、C、C ++、およびJavaプログラマーにとっては驚きであるためです。そして、それは警告さえ生成しませんか?サイレントな予期しない障害は非常に悪いです。

動作を明示的にすることを要求するのが最も安全なオプションであり、それがC#が採用したルートです。(そして、コンパイラーが暗黙のフォールスルーについて警告できるように、C ++がフォールスルーの明示的な構文を開発することを望みます)

于 2011-08-09T01:33:30.117 に答える