【问题标题】:Nested 'if'-'else' statements嵌套的 'if'-'else' 语句
【发布时间】:2011-09-08 13:03:02
【问题描述】:

如果检查它正在执行,我的代码与 if - else 非常混乱。分支和嵌套分支的数量相当大(超过 20 个 if - else if 和嵌套)。它使我的代码更难阅读,并且可能会成为性能问题。我的应用程序会检查从用户那里获得的许多条件,因此应用程序必须始终检查不同情况,例如:

如果文本框文本不为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;而不是继续进行信息处理。
  • 我有一种强烈的感觉 SelectedDate 来自日历控件,那些永远不能为空,你需要检查datePickerStart.SelectedDate == DateTime.MinValue
  • 代码运行良好,这不是我的问题。我要解决的问题是这种复杂的 if else 分支的可读性和性能

标签: c# switch-statement if-statement


【解决方案1】:

这不是性能狂。 Flattening Arrow Code 是一篇关于如何解决这些常见问题的精彩博文。

【讨论】:

  • 这看起来像我需要的,我会尽快检查并回复
【解决方案2】:

我在这里看到了一些混合验证。尝试从其他字段中移动一个字段,并分别验证它们,如下所示:

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's blog

【讨论】:

  • if ((StartInt != 0) && (EndInt != 0)) { 不是用于检查用户是否插入了整数。它用于检查 2 个文本框上的输入是否为 0。如果是,则做某事,否则做其他事情。就像我说的,一些 if else 语句用于输入验证,但大多数用于条件检查。
【解决方案3】:

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

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

然后使用这些“条件外观”属性

【讨论】:

    【解决方案4】:

    一些轻微的重构使我更容易阅读。我删除了无关的括号并合并了多个实际上只是 AND 逻辑的 IF 语句。

    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();
    }
    

    【讨论】:

      【解决方案5】:

      您可以使用有意义的名称定义自己的谓词或泛型函数,并将您的逻辑封装到其中。

      下面是一些谓词的代码示例:

      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&lt;&gt;Delegate&lt;&gt; 来使用 lambda 表达式编写小块条件 - 它既可以节省空间,又可以使您的代码更易于阅读。

      【讨论】:

        【解决方案6】:

        使用return 语句停止块的执行。

        例如,

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多