9

if ステートメントを変換してケースを切り替えようとしています (読みやすくするため)

1) 一般的に、switch ステートメントはひどいものだと読んだことがありますが、それは本当ですか? https://stackoverflow.com/questions/6097513/switch-statement-inside-a-switch-statement-c

2) ステートメントは次のようになります。

switch (Show)
                {
                    case Display.Expense:
                        if (expected.EXPENSE != true)
                            break;
                    case Display.NonExpense:
                        if (expected.EXPENSE == true)
                            break;
                    case Display.All:
                        //Code
                        break;
                }

エラーは次のとおりです。

コントロールは、あるケース ラベル (「ケース 1:」) から別のケース ラベルに移行できません。

これは元の if ステートメントです。

if ((Show == Display.All) || (expected.EXPENSE == true && Show == Display.Expense) || (expected.EXPENSE == false && Show == Display.NonExpense))
{
    //Code
}
4

8 に答える 8

14

まず、2 番目のポイントで質問するのを忘れていたことに気付きました。では、2 番目のポイントに対処するために、いくつか質問をさせていただきます。

"can't fall through" エラーの意味は何ですか?

C や C++ とは異なり、C# では、あるスイッチ セクションから別のスイッチ セクションへの偶発的なフォールスルーは許可されません。すべてのスイッチ セクションには、「到達不能なエンド ポイント」が必要です。break、goto、return、throw、または (まれに) 無限ループで終了する必要があります。

これにより、ブレークを入れ忘れて誤って「通り抜ける」というよくあるバグを防ぎます。

フォールスルーが合法であるかのようにコードを記述しました。私の推測では、あなたは C プログラマーだと思います。

C#でフォールスルーを強制するにはどうすればよいですか?

このような:

switch (Show)
{
case Display.Expense:
    if (expected.EXPENSE != true)
        break;
    else
        goto case Display.All;
case Display.NonExpense:
    if (expected.EXPENSE == true)
        break;
    else  
        goto case Display.All;
case Display.All:
    //Code
    break;
}

これで、到達可能性アナライザーは、「if」のどの分岐を使用しても、スイッチ セクションのエンドポイントに到達できないと判断できます。

これがスタイルいいの?

いいえ、元のコードははるかに読みやすいものでした。

一般的に、switch ステートメントはひどいものだと読んだことがありますが、それは本当ですか?

意見はさまざまです。Switch ステートメントは、動作が複雑な方法で相互作用しない非常に「鮮明な」選択肢が少数ある場合に非常に役立ちます。切り替えられたロジックは代わりに仮想メソッドまたはビジター パターンで処理する必要があると言う人もいますが、これも悪用される可能性があります。

この特定のケースでスイッチを使用する必要がありますか?

私はしません。

私のコードをどのように改善しますか?

if ((Show == Display.All) || 
    (expected.EXPENSE == true && Show == Display.Expense) || 
    (expected.EXPENSE == false && Show == Display.NonExpense))
{
    //Code
}

まず、C# ではすべて大文字で名前を付けないでください。

次に、ブール値を true と false で比較しないでください。それらはすでにブール値です。ステートメント X の真偽を知りたければ、英語で「X が真であることは真ですか?」とは言いません。「X は真ですか?」と言うでしょう。

私はおそらく次のように書くでしょう:

if (Show == Display.All || 
    Show == Display.Expense && expected.Expense || 
    Show == Display.NonExpense && !expected.Expense)
{
    //Code
}

または、さらに良いことに、テストを独自のメソッドに抽象化します。

if (canDisplayExpenses())
{ 
    //Code
}

または、すべてを抽象化します。

DisplayExpenses();
于 2013-04-01T15:19:40.570 に答える
3

読みやすさが必要な場合は、構文のゴミを捨ててください。

if (Show == Display.All || expected.EXPENSE && Show == Display.Expense || !expected.EXPENSE && Show == Display.NonExpense)
{
    //Code
}
于 2013-04-01T11:34:05.423 に答える
2

elseエラーがスローされないように、それぞれの部分を提供しますが、他の人が言うようにswitch、この場合は実際には必要ありません。

switch (Show)
{
    case Display.Expense:
         if (expected.EXPENSE != true)
             // do what you want
             break;
         else 
             // do what you want
             break;
    case Display.NonExpense:
         if (expected.EXPENSE == true)
             // do what you want
             break;
         else 
             // do what you want
             break;
    case Display.All:
        //Code
        break;
}
于 2013-04-01T11:33:04.273 に答える
0

Dennis に同意します。この問題に switch ケースは必要ありません。

おそらく読みにくいかもしれませんが、より短いものを使用することもできます:

if (Show == Display.All || (expected.EXPENSE == (Show == Display.Expense)))
{
    //Code
}
于 2013-04-01T11:47:44.853 に答える