7

Switch case ステートメントは、条件が同じで基準が異なる場合に、ネストされた if ステートメントを置き換えるのに適しています。しかし、ネストされた if ステートメントがすべて異なる固有の条件を持つ場合、どのようなアプローチがよいでしょうか? 相互にネストされた多数の if else ステートメントを置き換える代替オプションはありますか?

サンプルコード:

  • 注:これは非常に読みにくいことを知っています-これが要点です。
  • 注: すべての条件は一意です。

...

if (condition) {
    // do A
} else {                       
    if (condition) {
        // do B
    if (condition) {
        if (condition) {
            if (condition) {
                // do C
                if (condition) {
                    // do D
                    if (condition) {
                        // do E
                    } else {                                                   
                        if (condition) {
                            // do F
                        }
                    }
                }
            }

            if (condition) {
                // do G
                if (condition) {
                    // do H
                    if (condition) {
                        // do I
                    } else {
                        // do J
                    }
                }
            }
        }
    }
}

</p>

4

6 に答える 6

3

この場合の最善のアプローチは、適切な名前の個別のメソッドに分割することです。

于 2012-11-08T22:22:45.043 に答える
1

@Tar は、それを見る 1 つの方法を提案しました。別の可能性があります。

それを反転します。

if (myObject.HasThing1)
{
   if(myObject.HasThing2)
   {
      DoThing1();
   }
   else
   {
      DoThing2();
   }
}
else
{
   DoThing3();
}

になり得る

DoThing1(myObject.HasThing1);
DoThing2(myObject.HasThing2);
DoThing3(myObject.HasThing3);

したがって、各 Do メソッドは最小数のテストを行い、失敗した場合は何もしません。

いくつかの方法でシーケンスから抜け出したい場合は、少し賢くすることができます。

それがうまくいくかどうかはわかりませんが、条件のテストを委任することは、多くの場合、物事を見る新しい方法で十分であり、いくつかの単純化要因が魔法のように見えるかもしれません.

于 2012-11-08T22:45:03.437 に答える
1

コードを見たとき、これがDailyWTFではなくStackoverflowであることを確認する必要がありました!!

解決策は、アーキテクチャを変更し、インターフェイスとポリモーフィズムを使用してすべての条件を回避することです。ただし、それはおそらく大きな仕事であり、許容できる回答の範囲外であるため、独自の条件で Switch ステートメントを使用できる別の方法をお勧めします。

[Flags]
public enum FilterFlagEnum
{
    None = 0,
    Condition1 = 1,
    Condition2 = 2,
    Condition3 = 4,
    Condition4 = 8, 
    Condition5 = 16,
    Condition6 = 32,
    Condition7 = 64 
}; 


public void foo(FilterFlagEnum filterFlags = 0)
{
        if ((filterFlags & FilterFlagEnum.Condition1) == FilterFlagEnum.Condition1)
        {
            //do this
        }
        if ((filterFlags & FilterFlagEnum.Condition2) == FilterFlagEnum.Condition2)
        {
            //do this
        }
}


foo(FilterFlagEnum.Condition1 | FilterFlagEnum.Condition2);
于 2012-11-09T04:08:15.873 に答える
1

私の見解では、ネストされた条件を排除する主な方法が 2 つあります。最初のものは、次のように、ネストされた各条件に 1 つの条件しかない場合に、より特殊なケースで使用されます。

function A(){
    if (condition1){
        if (condition2){
            if (condition3){
                // do something
            }
        }
    }
}

return を使用して反対の状態から抜け出すことができます。

function A(){
    if (condition1 == false) return;
    if (condition2 == false) return;
    if (condition3 == false) return;  
    // do something 
}

2 つ目は条件分解を使用しており、最初のものよりも普遍的に扱うことができます。たとえば、次のような条件構造がある場合:

if (condition1)  
{
    // do this 1
}
else 
{                                                   
    if (condition2) 
    {
        // do this 2
    }                                                    
}

次のように、特定の条件ごとに変数を実装できます。

bool Cond1 = condition1;
bool Cond2 = !condition1 && condition2;

if (Cond1) { //do this 1 }
if (Cond2) { //do this 2 }
于 2012-11-08T22:39:18.783 に答える
0

それが本当にビジネスロジックである場合、構文は問題ありません。しかし、私はこれほど複雑なビジネスロジックを見たことがありません。フローチャートを作成し、それを単純化できないかどうかを確認します。

if (condition)  
{
    // do this
}
else 
{                                                   
    if (condition) 
    {
        // do this
    }                                                    
}

で置き換えることができます

if (condition)  
{
    // do this
}
else if (condition) 
{
    // do this                                                    
}

しかし、もう一度戻って設計を確認してください。クリーンアップする場合は、他のもの以上のものが必要です。

于 2012-11-08T22:42:20.403 に答える