2012-06-26 98 views
1

,你会在这种情况下做些什么来减少圈Complexty如何降低圈复杂的if-else语句

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个或更多。

+12

我认为减少圈复杂性本身不应该是一个目标。编写可读代码应该。 – svick

+0

是名称,年龄等,多态,还是他们共享一个有用的基类? – GregRos

+3

你确定这是做你想做的事吗?你想只设置一种背景颜色吗?或者您是否希望_every_项目的背景设置为空? – NominSim

回答

2

它看起来像你在每个“文本框”(至少我认为他们是文本框)执行相同的逻辑。我建议把所有的人都到一个集合并执行以下逻辑:

// 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.Background = Brushes.LightSteelBlue;之后放置一条break;语句,并且只有第一个空的“文本框”将设置其背景色。

+0

这不会执行与OP代码相同的功能。 – NominSim

+0

@NominSim如果你在'if'里面添加了一个'break',它会。 – svick

+0

@svick这将是接近的,你将不得不添加一些其他的条款来捕捉最后一种情况......我会反过来切换我的-1,但因为OP已经指定它只是一个例子。 – NominSim

2

例如,对于这种混凝土情况下,你可以

  • 定义Dictionary<string, dynamic> dic,其中关键是字符串值和价值是动态的(名称年龄 ...不管)

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

只是一个例子。

可能想要选择dynamic与否。可能是一些更加直观和易于理解,但其基本思想是:

化妆用字典的与主要基于if右值和的值等一些操作/方法/对象。

希望这会有所帮助。

+1

每次有人使用''dynamic''不是因为互操作性,而是因为他想用动态语言编写代码,所以小猫死在某处;)认真地说,为什么要使用强类型语言,如果你想做动态的东西?我不知怎的不喜欢它... –

+0

@PhilipDaubmeier:这就像打开你的翅膀,从山上跳下来。如果一个人不知道飞行,就不要跳。事实上,我解释了解决方案背后的* basic *思想,并给出了一些自定义实现,可能*或*可能不会被选择。 – Tigran

+0

是的,我明白你的观点。我只想指出,在使用'dynamic''之前,人们应该考虑他们是否真的需要。 –

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. 
} 

虽然这些更可读吗?嗯...可能不是。