2011-09-12 42 views
2

舊的驗證代碼通常檢查一個布爾條件,如果該條件爲真則拋出異常。重構方法參數驗證代碼到合同 - 語句反轉問題

而是Contract.Requires(...)做了相反的事情(通過檢查我們需要否定舊條件)。

我反駁舊代碼,有時會看到一些相當先進的布爾語句,顛倒它們並不容易,只是在做Contract.Requires(!(*old statements*))看起來很糟糕,很混亂。

如果它有類似於Contract.RequiresNot()的重構,那麼在這裏重構將更加清晰明瞭。

我們也不能添加靜態擴展方法。如果有人遇到這個問題,並找到一些很好的解決方案,我希望聽到它。

+0

如果他們是複雜的,你也應該試圖打破他們,至少在每一個&&。 –

+0

當然,我完全同意你的看法,那會更好,你必須同意我的觀點,即打破appart布爾語句也可以看作是一個錯誤源。它有時並不那麼微不足道。在某些情況下,id而不是觸摸它們,但仍然使用Contracts。 –

回答

1

您可以嘗試保留舊的舊驗證並在驗證後立即添加Contract.EndContractBlock調用。來自MSDN:

大多數代碼包含if-then-throw代碼形式的一些參數驗證。合同工具在以下情況下將這些語句識別爲先決條件:

當if-then-throw語句出現在此表單中時,工具將它們識別爲遺留需要語句。如果沒有其他合同遵循if-then-throw序列,則使用Contract.EndContractBlock方法結束代碼。

if (x == null) throw new ... 
Contract.EndContractBlock(); // All previous "if" checks are preconditions 

請注意,上述測試中的條件是否定的前提條件。 (實際的前提條件是x!= null。)否定前提條件受到高度限制:必須按前面示例中所示寫入;也就是說,它應該不包含else子句,並且then子句的主體必須是單個throw語句。 if測試受制於純度和可見性規則(請參見Usage Guidelines),但throw表達式僅受純度規則約束。但是,拋出的異常的類型必須與合同發生的方法一樣可見。

+0

是的,我在考察Contracts類的可用方法時考慮到了這一點,我記得它是被遺傳的方法。然而,我可以認爲這種「重構」不完整,單線合同聲明看起來好得多,如果拋出。它更多的是「無需重構,只需在舊語句解決方案之後插入EndContractBlock」即可。關於這些限制規則,與合同的方法清晰度相比,它們並不是那麼自然。需要......我想一想,謝謝。 –

1

您可以將old statements的結果存儲到具有正確名稱的布爾變量中。這將擺脫一對令人困惑的括號,也用於自我記錄你的代碼=)