web-dev-qa-db-ja.com

C#がオプションではないのになぜ壊れているのですか?

VS2008 C#でswitchステートメントを次のように作成すると(想定):

switch (state) {
    case '1':
        state = '2';
    case '2':
        state = '1';
}

それは私が通り抜けることができないと文句を言います:

コントロールは、1つのケースラベル(「ケース '1'(0x31):」)から別のケースラベルにフォールスルーできません。

ドロップスルーが許可されていない場合、breakステートメントの目的は何ですか?なぜ言語設計者はそれをそのままにして、不必要な構造を強制せずにswitchステートメントの最後に自動的にジャンプしなかったのですか?

91
paxdiablo

馬の口から(MSDN) C#switchステートメントがフォールスルーを許可しないように設計されているが、それでもブレークが必要なのはなぜですか?

顕著な部分を引用すると、これがフォールスルーを許可しない理由です。

この暗黙的なフォールスルー動作は、多くの場合、必要なコードの量を減らすために使用され、多くの場合、コードが初めて作成されたときには問題になりません。ただし、コードが初期開発フェーズからメンテナンスフェーズに移行すると、上記のコードにより、デバッグが非常に難しい微妙なエラーが発生する可能性があります。これらのエラーは、ケースを追加する開発者の非常に一般的な間違いに起因しますが、ブロックの最後にブレークを入れることを忘れています。

C#では、switchステートメントは、break、goto、return、またはthrowのいずれかのケースの終わりに明示的なフロー制御が発生することを必要とします。開発者がフォールスルーセマンティクスを希望する場合は、caseステートメントの最後にある明示的なgotoによって実現できます。

これが自動ではない理由です:

ケースブロックの最後に明示的なフロー制御が必要なC#ルール(通常はブレーク)の結果、多くの人々は、フォールスルーが発生しないように動作が単に変更されなかった理由を疑問視しています。つまり、ブレークを必要とせず、単にスイッチのセマンティクスを変更して、ケースのフォールスルーが発生しないようにします。これが行われなかった理由は、C++に非常に慣れている開発者がswitchステートメントが何をしているのかを理解するのに苦労しないようにするためでした。

73
Alex K.

基本的に、C/C++/Java開発者がより使いやすくするため。個人的には間違いだと思いますが、それが理由です。

私は強制ブロックを好んだでしょう:

case '1':
{
}

他のことは別として、それはスイッチ/ケースの奇妙な変数スコーピング状況を回避したでしょう。もちろん、複数のケースラベルを使用できます。

case '0':
case '1':
{
}

また、複数のケースをより簡単にリストできることもいいでしょう。

case '0', '1':
{
}

ああ、そして、既存の言語のあなたの説明についてのちょっとしたちょっとした選択:あなたはhave休憩をとらないでください。それは、ケースの終わりが到達不能でなければならないということだけです。 throwgoto、またはreturnを使用することもできます。私が見逃した他の人もいるかもしれません:)

87
Jon Skeet

ドロップスルーは許可されていますが、gotoキーワードを使用して明示的ににする必要があります。

switch (state) {
    case '1':
        state = '2';
        goto case '2';
    case '2':
        state = '1';
        break;
}

C#でbreakまたはgotoを使用できますが、実行できないのは、それが見つけにくいバグの潜在的な原因であるため、希望する状態ではありません。

goto(またはその逆)が必要なときにコードがbreakと言っているのを見つけるのは、どちらかを追加するのを忘れたのを見つけるよりもはるかに簡単です。

馬鹿げているように聞こえるかもしれませんが、C++バグの原因を探すための2時間の疲れた検索の多くは、breakを追加するのを忘れ、コードが常に失敗するという突然の認識に終わります。 C#では、必要なものを強制的に記述することでこれを回避します。

43
Chris

ケース1にコードがない場合、失敗することが許可されているため、「これらのケースはすべてこのコードを共有している」と言うことができます。

12
simendsjo