嵌套的“if-else”语句

7
我有一段非常混乱的代码,其中使用了很多 if-else 的判断语句。嵌套的条件分支很多(超过20个),这样会让我的代码难以阅读,并且可能会成为性能瓶颈。我的应用程序需要检查用户提供的很多条件,因此必须不断检查不同的情况,例如:

如果文本框中的文本不为0,则继续执行下一个步骤...

if ((StartInt != 0) && (EndInt != 0))   
{

然后它会检查用户是否选择了日期:

if ((datePickerStart.SelectedDate == null) || (datePickerEnd.SelectedDate == null)) 
{
    MessageBox.Show("Please Choose Dates");
}

如果日期选择器不为空,则继续执行代码...

else if ((datePickerStart.SelectedDate != null) && (datePickerEnd.SelectedDate != null))
{
    // CONDITIONS FOR SAME STARTING DAY AND ENDING DAY.
    if (datePickerStart.SelectedDate == datePickerEnd.SelectedDate)
    {
        if (index1 == index2)
        {
            if (StartInt == EndInt)
            {
                if (radioButton1.IsChecked == true)
                {
                    printTime3();
                }
                else
                {
                    printTime();
                }
            }

这只是正在进行的检查的一小部分。其中一些是功能性的,一些是用于输入验证的东西。

有没有办法使其更易读且减少性能消耗?


如果您在方法或事件内部进行验证,那么最好在其前面进行验证,例如:if(dtp.SelectedDate == null) return; 然后再进行信息处理。 - Rosmarine Popcorn
1
我有强烈的感觉SelectedDate是来自一个日历控件,这些控件永远不会为空,你需要检查datePickerStart.SelectedDate == DateTime.MinValue - Scott Chamberlain
代码运行良好并不是我的问题。我指的问题是这样复杂的if else分支结构的可读性和性能。 - Yosi199
6个回答

13

它并不是一个性能劣质的东西。如何解决那些常见问题的一个很棒的博客文章是箭头代码平滑化


那看起来就是我需要的,我很快会检查并回复。 - Yosi199

3

我看到验证中存在一些混淆。尝试将一个字段与其他字段分开,并分别进行验证,像这样:

if (StartInt == 0 || EndInt == 0)
{
    MessageBox.Show("Please Choose Ints");
    return;
}
if (datePickerStart.SelectedDate == null || datePickerEnd.SelectedDate == null)
{
    MessageBox.Show("Please Choose Dates");
    return;
}

在这种方法中,您将始终告诉用户他做错了什么,您的代码会更简单。
更多信息请参见Jeff的博客

if ((StartInt != 0) && (EndInt != 0))
{这不是用来检查用户是否插入整数的。它是用来检查两个文本框中的输入是否为0。如果是,则执行某些操作,否则执行其他操作。就像我说的那样,一些if else语句用于输入验证,但大多数用于条件检查。
- Yosi199

2

一种方法是通过以下方式封装复杂条件进行重构:

public bool DateRangeSpecified
{
  get 
  {
    return (datePickerStart.SelectedDate != null) 
           && 
           (datePickerEnd.SelectedDate != null)
           && StartInt != 0 && EndInt != 0; 
  }
}

然后使用这些“条件门面”属性


0
使用return语句来停止代码块的执行。
例如,
void Test()
{
    if (StartInt==0 || EndInt==0)
    {
        return;
    }

    if (datePickerStart.SelectedDate == null || datePickerEnd.SelectedDate == null)
    {
        MessageBox.Show("Please Choose Dates");
        return;
    }
}

0
一些轻微的重构让代码更易于阅读。我删除了多余的括号并合并了多个 IF 语句,这些语句实际上只是 AND 逻辑。
if (StartInt == 0 || EndInt == 0)    
    return;
if (datePickerStart.SelectedDate == null || datePickerEnd.SelectedDate == null)
{
    MessageBox.Show("Please Choose Dates");  
    return;           
}
if (datePickerStart.SelectedDate != null 
    && datePickerEnd.SelectedDate != null
    && datePickerStart.SelectedDate == datePickerEnd.SelectedDate
    && index1 == index2
    && StartInt == EndInt)
{
    if (radioButton1.IsChecked == true)
        printTime3();
    else
        printTime();
}

0
你可以定义自己的谓词或通用函数,并使用有意义的名称封装你的逻辑。
以下是一些谓词的代码示例:
public Predicate<DateTime> CheckIfThisYear = a => a.Year == DateTime.Now.Year;
public Func<DateTime, int, bool> CheckIfWithinLastNDays = (a, b) => (DateTime.Now - a).Days < b;

现在你可以轻松地在你的代码中编写

if (CheckIfThisYear(offer) && CheckIfWithinLastNDays(paymentdate,30)) ProcessOrder();

考虑使用泛型委托,如 Func<>Delegate<> ,使用 lambda 表达式编写条件的小代码块 -- 这样既可以节省空间,也使您的代码更加易读。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接