2010-07-22 26 views
5

从代码清晰度的角度来看,是否有更好的方式来编写大量AND检查而不是大型IF语句的条件?如何使大的if语句更具可读性

例如我目前需要在屏幕上创建一个字段,如果其他字段不符合特定要求。目前我有一个超过30 LOC的IF语句,这看起来不正确。

if(!(field1 == field2 && 
    field3 == field4 && 
    field5 == field6 && 
    . 
    . 
    . 
    field100 == field101)) 
{ 
    // Perform operations 
} 

解决方案是简单地将它们分解为更小的块并将结果分配给更少数量的布尔变量?使代码更易读的最佳方式是什么?

感谢

+0

这些字段中存储了哪些类型的值?用户可以修改它们吗?它们是否是静态的,即它们是否固定值下拉框? – 2010-07-22 15:02:46

+0

他们都是字符串值,有些是只读的,但不是静态的 – Longball27 2010-07-22 15:07:32

回答

9

我会考虑建立规则,谓语形式:

bool FieldIsValid() { // condition } 
bool SomethingElseHappened() { // condition } 
// etc 

然后,我会创造我自己这些谓词的列表:

IList<Func<bool>> validConditions = new List<Func<bool>> { 
    FieldIsValid, 
    SomethingElseHappend, 
    // etc 
}; 

最后,我会写的条件,使转发条件:

if(validConditions.All(c => c()) 
{ 
    // Perform operations 
} 
+1

这就是我正在建议的。谓词是使代码更具表现力,并将所有条件保存在一个地方的好方法。 – drharris 2010-07-22 14:59:39

1

就个人而言,我觉得破成大块这样只会让整个语句不太清楚。这将使代码更长,而不是更简洁。

我可能会将此检查重构为类中的方法,以便您可以根据需要重用它,并在单个位置对其进行测试。不过,我很可能会把支票写下来,如果有条件的话,每行一个。

1

您可以将条件重构为单独的函数,也可以使用De Morgan's Laws稍微简化逻辑。

另外 - 是你的变量真的都叫fieldN

+0

不,他们不是,我想我会简化我的问题! – Longball27 2010-07-22 15:01:21

0

你可以利用的所有变量之间是否存在其他一些关系?

例如,他们是否都是两个类的成员?

如果是这样,并且提供您的性能要求不排除这一点,您可以将它们的引用全部拖拽到List或数组中,然后在循环中对它们进行比较。有时你可以在对象构造上做到这一点,而不是每次比较。

在我看来,真正的问题是架构中的其他地方而不是if()语句 - 当然,这并不意味着它可以很容易地修复,我明白这一点。

1

我的易读性改变的第一件事是通过反转语句删除几乎隐藏否定(通过使用De Morgan's Laws):

if (field1 != field2 || field3 != field4 .... etc) 
{ 
    // Perform operations 
} 

虽然使用了一系列的& &而非||确实有一些轻微的性能改进,我觉得缺少与原始代码的可读性值得改变。

如果表现是一个问题,您可以将这些陈述分解为一系列的if语句,但到那时会变得一团糟!

+0

我不确定你的逻辑是否正确 - 你有没有用过德摩根定律来简化逻辑,而不是颠倒它? – 2010-07-22 14:58:04

+0

是的,绝对..好点!固定。 – 2010-07-22 15:04:36

1

问题的一部分是你混合元数据和逻辑。

哪些问题是必需的(/必须是等于/最小长度/等)是元数据。

验证每个字段满足它的要求是程序逻辑。

需求列表(以及应用的字段)应该全部存储在其他地方,而不是在大的if语句中。

然后您的验证逻辑读取列表,循环访问并保持运行总数。如果任何字段失败,您需要提醒用户。

0

这不是什么arrays基本上是为了什么?

而不是100 variables命名为fieldn,创建一个array100 values

然后,如果条件匹配,则可以在数组中包含loop组合的函数,如果条件匹配,则可以使用return true or false

1

开始使用C#的工作流引擎可能很有用。它专门用于帮助图形化地布置这些复杂的决策算法。

Windows WorkFlow Foundation

2

正确的方法将取决于您没有提供细节有所不同。如果要比较的项目可以通过某种索引(数字计数器,字段标识符列表等)进行选择,那么最好不要这样做。例如,如下所示:

 
Ok = True 
For Each fld as KeyValuePair(Of Control, String) in CheckFields 
    If fld.FormField.Text fld.RequiredValue Then 
    OK = False 
    Exit For 
    End If 
Next 

构造控件和字符串列表可能有点麻烦,但有合理的方法。