如何在if-else语句中减少Cyclomatic复杂性

时间:2012-06-26 13:37:06

标签: c# cyclomatic-complexity

在这种情况下,您将采取什么措施来降低Cyclomatic Complexity

if (Name.Text == string.Empty)
    Name.Background = Brushes.LightSteelBlue;

else if(Age.Text == string.Empty)
    Age.Background = Brushes.LightSteelBlue;

else if(...)
    ...

else
{
    // TODO - something else
}

假设我有30个或更多。

3 个答案:

答案 0 :(得分:2)

看起来你在每个“TextBox”上执行相同的逻辑(至少我认为它们是TextBoxes)。我建议将所有这些内容放入一个集合中并执行以下逻辑:

// Using var, since I don't know what class Name and Age actually are
// I am assuming that they are most likely actually the same class
// and at least share a base class with .Text and .BackGround
foreach(var textBox in textBoxes)
{
    // Could use textBox.Text.Length > 0 here as well for performance
    if(textBox.Text == string.Empty)
    {
        textBox.Background = Brushes.LightSteelBlue;
    }
}

注意:这确实会改变你的代码,因为我注意到你只检查一个“TextBox”的值,只有前一个没有空文本。如果你想保持这个逻辑,只需在break;之后放一个textBox.Background = Brushes.LightSteelBlue;语句,只有第一个空的“TextBox”将设置它的背景颜色。

答案 1 :(得分:2)

例如对于这个具体的案例,您可以

  • 定义Dictionary<string, dynamic> dic,其中KEY是字符串值,VALUE是动态的(名称年龄 ......无论如何)

  • 做dic [stringValue] .Background = Color.LightSteelBlue;

只是一个例子。

可能想要选择dynamic。可能更直观,更容易理解,但基本思路是:

根据if右值使用带有键的字典,并像某个操作/方法/对象一样使用值。

希望这有帮助。

答案 2 :(得分:0)

我完全同意svick的评论。在某些情况下,以下方法可能是好的(但不是为了减少圈复杂度,通常是为了创建可插拔的决策者):

public class SwitchAction{
  public Func<bool> Predicate { get; set; }
  public Action TheAction { get; set; }
}

public List<SwitchAction> SwitchableActions = new List<SwitchAction>();

public void InitialiseSwitchableActions()
{
   SwitchableActions.AddRange(new[] {
     new SwitchAction() { Predicate = () => Name.Text == string.Empty, 
                          TheAction = () => Name.Background = Brushes.LightSteelBlue },
     new SwitchAction() { Predicate = () => Age.Text == string.Empty, 
                          TheAction = () => Age.Background = Brushes.LightSteelBlue },
   });
}

public void RunSwitchables()
{
  var switched = SwitchableActions.FirstOrDefault(s => Predicate());

  if(switched != null)
    switched.TheAction();
  else
    //TODO: something else.
}

当然 - 如果实际上这些行为不是相互排斥的,你必须稍微改变最后一种方法:

public void RunSwitchables()
{
   bool runCatchAll = true;
   foreach(var switched in SwitchableActions.Where(a => a.Predicate())
   {
     switched.TheAction();
     runCatchAll = false;
   }

   if(runCatchAll)
     //TODO: Something else.
}

这些中的任何一个都更具可读性吗?嗯......可能不是。