2010-07-22 29 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 

構造控件和字符串列表可能有點麻煩,但有合理的方法。