简化C#代码中的case-if-else梯形图

时间:2014-02-12 09:43:34

标签: c# if-statement refactoring

编辑:我对特定的编程实践或编码方式更感兴趣,以避免这种情况。但任何建议都是受欢迎的。

我写了这个丑陋的代码来执行某些任务:

switch(arg[0])
{ 
    case "a"
    {
        foreach(var c in obja)
        {
            if(c.entry == 'a')
            {
                if (Independent_condition_1)
                {
                    // do logging
                    continue;
                }
                if (Independent_condition_2)
                {
                    // do logging
                    continue;
                }
                // Do something if above two conditions are false
            }
            else
            {
                if (Independent_condition_3)
                {
                    // do logging
                    continue;
                }
                if (Independent_condition_4)
                {
                    // do logging
                    continue;
                }
                // do something if above 2 conditions are false.
            }
        }
        break;
    }
    case "b"
    {
        // similar if else ladder
    }   
}

问题是代码看起来很难看,而且非常难以理解。为了简化代码,我已将if-else中的大部分内容移动到函数中。这种长嵌套if-else的替代方法是什么?

4 个答案:

答案 0 :(得分:2)

你可以创建一个方法来执行if / else的东西并在交换机内调用它,你不会复制代码而你不会有一个巨大的开关块:

switch(arg[0])
{
     case "a":
        DoStuff('a');
        break;
     case "b":
        DoStuff('b');
        break;
     default:
        break;
}

private void DoStuff(char c)
{
   foreach(var c in obja)
   {
       if(c.entry == c)
       {
           if (Independent_condition_1)
           {
               // do logging
               continue;
           }
           if (Independent_condition_2)
           {
                // do logging
                continue;
           }
              // Do something if above two conditions are false
        }
        else
        {
            if (Independent_condition_3)
            {
                // do logging
                continue;
            }
            if (Independent_condition_4)
            {
                // do logging
                continue;
            }
            // do something if above 2 conditions are false.
        }
    }
}

答案 1 :(得分:1)

首先,您的代码中有许多不必要的分支。我会结合并否定它们。这将使代码更具可读性。

switch(arg[0])
{ 
 case "a"
 {
  foreach(var c in obja)
  {
     if(c.entry == 'a')
     {
        if(!(Independent_condition_1 || Independent_condition_2))
        {
          // Do something
        }
      }
     else
      {
       if(!(Independent_condition_3 || Independent_condition_4)
        {
         // do something
        }
       }
     break;
      }
 case "b"
  {
  //similar if else ladder
  }   
}

接下来我将其分解为不同的方法。通过将方法命名为适合您的域名的方法,您将使代码更具可读性。这也意味着当您进行更改时,您只需要考虑您正在处理的小部分,而不是整个复杂的方法。 / p>

switch(arg[0])
{ 
 case "a"
 {
  foreach(var c in obja)
  {
     newMethod(c);
     break;
      }
 case "b"
  {
  //similar if else ladder
  }   
}

void newMethod(str c) {
  if(c.entry == 'a')
     {
        if(!(Independent_condition_1 || Independent_condition_2))
        {
          // Do something
        }
      }
     else
      {
       if(!(Independent_condition_3 || Independent_condition_4)
        {
         // do something
        }
       }
}

然后,您可以继续将其分解为更小的命名方法,直到更容易理解为止。

答案 2 :(得分:0)

您可以创建许多私有方法来制定决策或处理单个案例,或者将单个案例的逻辑封装在单独的类中。后者使测试更容易,而前者只是防止你的代码变得笨拙。

我倾向于在单一方法中瞄准不超过5的圈复杂度(如果我能帮助它......)http://msdn.microsoft.com/en-us/library/ms182212.aspx

使用私有方法的代码示例:

 private void method(string[] arg)
    {
        switch (arg[0])
        {
            case "a":
                HandleCaseA();
                break;

            case "b":
                HandleCaseB();
                break;
            default:
                throw new ArgumentException("arg");
        }
    }



    private void HandleCaseA()
    {
        foreach (var c in obja)
        {
            if (c.entry == 'a')
                HandleSubCaseA();
            else if (!(Independent_condition_3 || Independent_condition_4)
            HandleSubCaseAWithConditions3And4();

        }           
    }

    private void HandleSubCaseA()
    {
        if (!(Independent_condition_1 || Independent_condition_2))
            {
                // Do something
            }
        }
    }

    private void HandleCaseB ()
    {
        //Do stuff
    }

    private void HandleSubCaseAWithConditions3And4()
    {
        //Do stuff
    }
}

答案 3 :(得分:0)

你可以在方法中加入条件和处理。如果条件在您编写时是独立的,则没有开关,因此您必须将工作分成更易读(或不太可读)的块,如下所示:

if (c.entry == 'a')
{
     ProcessEntryA(c);
} else ...
     // etc
}