C# Switch语句重构

4
以下代码的目的是确定特定日期是否符合“周末”的定义,即在星期四下午12:00之后,至少2天并在星期一上午12:00之前。
有没有更好的方法?使用if-else语句会变得很丑陋,而策略模式对于这个问题来说过于繁琐。
public bool ValidateWeekend(DateTime pickupDate, DateTime dropoffDate)
    {
        TimeSpan ts = dropoffDate.Subtract(pickupDate);

        if (ts.TotalDays >= 2 && ts.TotalDays <= 4)
        {
            switch (pickupDate.DayOfWeek)
            {
                case DayOfWeek.Thursday:
                    if (pickupDate.Hour >= 12)
                    {
                        switch (dropoffDate.DayOfWeek)
                        {
                            case DayOfWeek.Sunday:
                                return true;
                            case DayOfWeek.Monday:
                                if (dropoffDate.Hour <= 12)
                                {
                                    return true;
                                }
                                return false;
                        }
                    }
                    break;
                case DayOfWeek.Friday:
                    switch (dropoffDate.DayOfWeek)
                    {
                        case DayOfWeek.Sunday:
                            return true;
                        case DayOfWeek.Monday:
                            if (dropoffDate.Hour <= 12)
                            {
                                return true;
                            }
                            return false;
                    }
                    break;
                case DayOfWeek.Saturday:
                    switch (dropoffDate.DayOfWeek)
                    {
                        case DayOfWeek.Sunday:
                            return true;
                        case DayOfWeek.Monday:
                            if (dropoffDate.Hour <= 12)
                            {
                                return true;
                            }
                            return false;
                    }
                    return false;
            }
        }
        return false;
    }

除了将重复的代码重构为自己的方法,如下所列,我非常喜欢使用更具功能性的方法来解决问题。将每天的逻辑隔离到自己特定的函数中,然后构建一个以天数为键和相应方法为值的映射。通过将接送日期放入自己的方法中,如上所述,然后使用lambda来执行您的卸货逻辑,我认为代码变得更加清晰简洁。 - San Jacinto
9个回答

6

你一定应该重构掉dropoffDate——因为代码重复了三次!最简单的清理方法是:我会引入一个函数来检查pickupDate,再引入另一个函数来检查dropoffDate:

private bool IsPickupWeekend(DateTime pickupDate)
{
    switch (pickupDate.DayOfWeek)
            {
                case DayOfWeek.Thursday:
                    return pickupDate.Hour >= 12;
                case DayOfWeek.Friday:                    
                case DayOfWeek.Saturday:
                    return true;
            }
        }
        return false;
}

private bool IsWeekendDropOff(DateTime dropoffDate)
{
    switch (dropoffDate.DayOfWeek)
                    {
                        case DayOfWeek.Sunday:
                            return true;
                        case DayOfWeek.Monday:
                            if (dropoffDate.Hour <= 12)
                            {
                                return true;
                            }
                            return false;
                    }
                    return false;

}

现在你的主要函数只需要两行:

if (ts.TotalDays >= 2 && ts.TotalDays <= 4)
{
    return IsPickupWeekend(pickupDate) && IsWeekendDropOff(dropoffDate);
}

很确定这将检查上午12点而不是下午12点。 - James
@Grzenio:IsWeekendDropOff函数不应该将星期六作为放车日吗?考虑到取车日期是星期四下午1点,那么还车日期可以是星期六下午2点。 - Ashish Jain
请参阅http://msdn.microsoft.com/en-us/library/system.datetime.hour.aspx,特别是“小时组件,表示为0到23之间的值”。 - James
问题中提到的12 PM是指中午12点,即在0-23小时制中,它是12点,因此星期六不应该被考虑为DropOff的一天吗? - Ashish Jain
我刚刚从问题中复制了代码片段 - 作者只要求提供一个“不那么丑陋”的版本 - 所以我认为问题中的代码是“正确的”。 - Grzenio

3
我认为你可以在这里提取一个方法:
private bool ValidateDropoff(DateTime dropoffDate)
{
    switch (dropoffDate.DayOfWeek)
    {
        case DayOfWeek.Sunday:
           return true;
        case DayOfWeek.Monday:
           return dropoffDate.Hour <= 12;
        default:
           return false;
    }
}

你需要在结尾处加上 'return false;',否则并不是每个路径都会返回一个值。或者,只需将你已经写在 switch 外面的 'return false;' 移动到里面即可。 - Gorpik
1
@Gorpik,默认情况下会处理这个。实际上,每个路径都会返回一个值。 - bruno conde
这段代码中难道不应该包含周六吗?请问在取车日期为星期四下午1点,还车日期为星期六下午2点的情况下,这段代码是否有效? - Ashish Jain

1
if (ts.TotalDays >= 2 && ts.TotalDays <= 4)
{
    var hour_limit = new Func<Boolean>(() => {
        switch (dropoffDate.DayOfWeek)
        {
            case DayOfWeek.Sunday:
                return true;
            case DayOfWeek.Monday:
                return dropoffDate.Hour <= 12;
            default:
                return false;
        }

    });

    switch (pickupDate.DayOfWeek)
    {
        case DayOfWeek.Thursday:
            if (pickupDate.Hour >= 12)  return hour_limit();
            break;
        case DayOfWeek.Friday:
        case DayOfWeek.Saturday:
            return hour_limit();
        default: 
            break;
    }
}

return false;

0

虽然不是很清楚,但这是你要的:

public bool ValidateWeekend(DateTime pickupDate, DateTime dropoffDate){
    TimeSpan ts = dropoffDate.Subtract(pickupDate);

    if (ts.TotalDays >= 2 && ts.TotalDays <= 4){
        switch (pickupDate.DayOfWeek){
            case DayOfWeek.Thursday:
                if (pickupDate.Hour >= 12){
                    switch (dropoffDate.DayOfWeek){
                        case DayOfWeek.Sunday:
                            return true;
                        case DayOfWeek.Monday:
                            return dropoffDate.Hour <= 12;
                    }
                }
                break;
            case DayOfWeek.Friday:
                switch (dropoffDate.DayOfWeek){
                    case DayOfWeek.Sunday:
                        return true;
                    case DayOfWeek.Monday:
                        return dropoffDate.Hour <= 12;
                }
                break;
            case DayOfWeek.Saturday:
                switch (dropoffDate.DayOfWeek){
                    case DayOfWeek.Sunday:
                        return true;
                    case DayOfWeek.Monday:
                        return dropoffDate.Hour <= 12;
                }
                return false;
        }
    }
    return false;
}

0

我的第一次尝试:

if (ts.TotalDays >= 2 && ts.TotalDays <= 4)
        {
            switch (pickupDate.DayOfWeek)
            {
                case DayOfWeek.Thursday:
                case DayOfWeek.Friday:
                case DayOfWeek.Saturday:
                    if (pickupDate.DayOfWeek == DayOfWeek.Thursday && pickupDate.Hour <= 12)
                        return false;

                    switch (dropoffDate.DayOfWeek)
                    {
                        case DayOfWeek.Sunday:
                            return true;
                        case DayOfWeek.Monday:
                            return dropoffDate.Hour <= 12;
                    }
                    return false;

                default:
                    return false;
            }
        }
        return false;

0

在 switch 中尝试

retrun (dropoffDate.DayOfWeek == DayOfWeek.Sunday && dropoffDate.Hour <= 12 || dropoffDate.DayOfWeek == DayOfWeek.Sunday)

0
我会这样做
public bool ValidateWeekend(DateTime pickupDate, DateTime dropoffDate)
{
    TimeSpan ts = dropoffDate.Subtract(pickupDate);

    if (ts.TotalDays >= 2 && ts.TotalDays <= 4)
    {
        switch (pickupDate.DayOfWeek)
        {
            case DayOfWeek.Thursday:
                if (pickupDate.Hour >= 12)
                {
                    reurn DayOfWeek(dropOffDate.DayOfWeek);
                }
                break;
            case DayOfWeek.Friday, DayOfWeek.Saturday:
                {
                    return DayOfWeek(dropOffDate.DayOfWeek);
                }
        }
    }
    return false;
}

public bool DayOfWeek(DateTime dropOffDate)
    {
switch (dropoffDate.DayOfWeek)
    {
        case DayOfWeek.Sunday:
            {
                return true;
            }
        case DayOfWeek.Monday:
            {
                if (dropoffDate.Hour <= 12)
                    {
                        return true;
                    }
                return false;
            }
       return false;
   }
 }

0

这是我的尝试:

  /// <summary>
    /// Gets the weekend days.
    /// </summary>
    /// <returns></returns>
    public List<DayOfWeek> GetWeekendDays()
    {
        List<DayOfWeek> days = new List<DayOfWeek>()
                                   {
                                       DayOfWeek.Thursday,
                                       DayOfWeek.Friday,
                                       DayOfWeek.Sunday
                                   };
        return days;
    }

    /// <summary>
    /// Validates the weekend.
    /// </summary>
    /// <param name="pickupDate">The pickup date.</param>
    /// <param name="dropoffDate">The dropoff date.</param>
    /// <returns></returns>
    public bool ValidateWeekend(DateTime pickupDate, DateTime dropoffDate)
    {
        bool isValid = false;
        TimeSpan ts = dropoffDate.Subtract(pickupDate);

        if (ts.TotalDays >= 2 && ts.TotalDays <= 4)
        {
            List<DayOfWeek> days = GetWeekendDays();

            foreach (DayOfWeek day in days)
            {
                if(pickupDate.DayOfWeek == day)
                {
                   isValid = ValidateDropOff(dropoffDate);
                    break;
                }
            }
        }

        return isValid;
    }

    /// <summary>
    /// Validates the drop off.
    /// </summary>
    /// <param name="dropoffDate">The dropoff date.</param>
    /// <returns></returns>
    private static bool ValidateDropOff(DateTime dropoffDate)
    {
        bool isValidDropOff = (dropoffDate.DayOfWeek == DayOfWeek.Sunday);

        if(dropoffDate.DayOfWeek == DayOfWeek.Monday)
        {
            if (dropoffDate.Hour <= 12)
            {
                isValidDropOff = true;
            }
        }

        return isValidDropOff;
    }

0
    private readonly TimeSpan Midday = new TimeSpan(12, 0, 0);

    public bool ValidateWeekend(DateTime pickupDate, DateTime dropoffDate)
    {
        TimeSpan lengthOfTrip = dropoffDate.Subtract(pickupDate);

        if (lengthOfTrip.TotalDays < 2 || lengthOfTrip.TotalDays > 4)
            return false;

        return IsPickupDateConsideredWeekend(pickupDate) && IsDropoffDateConsideredWeekend(dropoffDate);
    }

    private bool IsPickupDateConsideredWeekend(DateTime pickupdate)
    {
        if (pickupdate.DayOfWeek == DayOfWeek.Thursday && pickupdate.TimeOfDay > Midday)
            return true;
        return false;
    }

    private bool IsDropoffDateConsideredWeekend(DateTime dropoffDate)
    {
        if (dropoffDate.DayOfWeek == DayOfWeek.Monday && dropoffDate.TimeOfDay <= Midday)
            return true;
        return false;
    }

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