2015-12-21 86 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

相关问题