2015-12-21 38 views
3

我遇到了一個問題,因爲我在窗體中執行了大約5次驗證檢查。其中每個都位於其自己的方法Is_XXX_Valid()。我正在尋找一種方法來確定每種方法return true;否則應顯示錯誤消息。如何在執行操作前檢查所有方法是否正確

然而這是哪裏出了問題出現的時候,我有工作的一部分,因爲它無法運行的後續方法,如果前面的方法返回false

這裏是我使用的當前代碼的解決方案:

private void Button_Click(object sender, EventArgs e) 
    { 
    DialogResult validation_msgbox = MessageBox.Show("Are you sure you would like to submit this form?", "Submit Form?", MessageBoxButtons.YesNo); 

    // Run each validaion check 

    if (IsAAAValid() && IsBBBValid()) 
    { 
     //Continue and submit data 
    } 
    else 
    { 
     //Display the errors 
     DialogResult Textbox_validation = MessageBox.Show(ErrorText, "Some errors were found.", MessageBoxButtons.OK); 
    } 
    } 

使用代碼上面作爲一個例子,如果IsAAAValid()返回假,則不執行第二方法,並且因此內的數據未通過驗證,從而導致不正確的對話框如果發現多個錯誤。

謝謝!

+1

'&&'是短路的,所以第一個錯誤返回將導致不執行任何後續條件。只需使用'&',因爲它不是短路。 –

+1

你不能只爲每個方法調用做bool變量,並且對bool變量執行if()嗎? – wentimo

+2

如果你真的需要所有的方法來運行,那麼我認爲你的方法的責任沒有很好的命名/定義。我不希望名爲'IsXXX'的方法有你所暗示的副作用。 – sstan

回答

8

這被稱爲「短路評價」,它可以讀取關於here並且是C#編程語言的一個通常-期望的特徵。你可以避開它是這樣的:

bool avalid = IsAAAValid(); 
bool bvalid = IsBBBValid(); 
if (avalid && bvalid) 
{ 
    //Continue and submit data 
} 

這將保證這兩種方法得到運行。

作爲一個側面說明,爲了清楚起見,在你的代碼,我建議你重命名你的驗證方法,以表明他們有副作用。也就是說,他們不僅僅是簡單地返回數據的狀態;他們實際上有可能修改狀態。這就是短路評估在這種情況下會導致問題的原因。

6

由於adv12已經回答了,這就是所謂的短路評價,但也有對他的重構代碼的方式替代。

有兩個布爾運營商:

  • && - 短路評價
  • & - 全面評估

所以,你可以簡單地切換到使用&調用兩種方法不管:

if (IsAAAValid() & IsBBBValid()) 
       ^
       | 
       +-- only one &, not two && 

現在,說了這樣的話,我個人會將代碼編寫爲adv12,因爲它使代碼更容易閱讀,並不容易發現僅使用一個代碼&,但我認爲我會發布完整答案。

+2

很好的答案,尤其是建議不要那樣做:)。幾乎可以保證,下一個看到代碼的人會用'&&'替換'&'並調用原作者的名字......並且比一週後花一天時間試圖找出代碼不再正確報告錯誤的原因。 –

+0

@AlexeiLevenkov是的,依賴布爾表達式中的副作用是非常粗略的。但分手和記錄結果更具可讀性。 – ryanyuyu

4

你可以簡單地調用每一個方法,並設置一個布爾值false,如果任何方法返回false。最後你可以檢查這個布爾值並顯示你的錯誤信息。

bool isValid = true; 
if(!IsValidA()) isValid = false; 
if(!IsValidB()) isValid = false; 
if(!IsValidC()) isValid = false; 
if(!IsValidD()) isValid = false; 
if(!IsValidE()) isValid = false; 
if(!isValid) 
    MessageBox.Show("Global validation error message"); 

不過我更喜歡在你使用List<string>累積的錯誤信息並打印全部結束

List<string> errors = new List<string>(); 
if(!IsValidA()) errors.Add("Fail on IsValidA"); 
if(!IsValidB()) errors.Add("Fail on IsValidB"); 
if(!IsValidC()) errors.Add("Fail on IsValidC"); 
if(!IsValidD()) errors.Add("Fail on IsValidD"); 
if(!IsValidE()) errors.Add("Fail on IsValidE"); 

if(errors.Count > 0) 
{ 
    string message = string.Join(Environment.NewLine, errors.ToArray()); 
    MessageBox.Show("Validation errors found:" + Environment.NewLine + message); 
} 

我覺得這是從用戶的角度更好,因爲你可以告訴一個更好的辦法她/他的單個消息中發現的問題,並避免當您告訴用戶關於單個問題時發生的可怕的用戶體驗,用戶只會修復問題以獲得有關另一個問題的其他錯誤消息。

+1

用布爾值替換第一個代碼示例中的計數,例如'notValid',如果測試在將來的代碼維護期間發生變化,將不需要測試'5'並更新值。強烈建議第二個代碼示例將有用信息傳回給用戶。 – HABO

+0

對,它會有點混亂,但你是正確的 – Steve

+0

會使用'isValid&= IsValidA(); ......「更有吸引力?它不會短路。 – HABO

相關問題