周期与 c# 8 中的模式匹配重叠

Period overlap with Pattern Matching in c# 8

随着 c# 8 中模式匹配的增强,一直想知道是否有更好的写法:

private bool HasOverlapTime(TimeSpan requestFrom, TimeSpan requestTo, TimeSpan detailFrom, TimeSpan detailTo)
{
    var timesOverlap = (requestFrom >= detailFrom && requestFrom < detailTo); //time From falls into range

    timesOverlap = !timesOverlap ? requestTo <= detailTo && requestTo > detailFrom : timesOverlap; // time to falls in range

    timesOverlap = !timesOverlap ? requestFrom <= detailFrom && requestTo >= detailTo : timesOverlap; // previous row false into new range

    return timesOverlap;
}

一个建议(不仅仅是一个答案)是使用逻辑运算符重构您的代码。它将减少代码大小和过度复杂化。

&= 和 |= 运算符很适合您的情况。

另一点 - 这次使用 C# 8 - 也适合解构模式。 它允许您从 class 中提取元组中的那些数据,然后将您的逻辑写入 C#8 "property pattern match" 开关中。

假设如果两个时间范围重叠,HasOverlapTime() 应该 return true,并且时间范围代表 "half-open" 个间隔(即范围的末尾)不包括在范围内),那么一个更简单的实现是:

private static bool HasOverlapTime2(TimeSpan requestFrom, TimeSpan requestTo, TimeSpan detailFrom, TimeSpan detailTo)
{
    return (detailTo > requestFrom) && (detailFrom < requestTo);
}

无需使用模式匹配来简化代码。

请注意,您的代码使用的是半开区间。相反,如果您想使用闭区间(即区间 包括 其结束时间),那么您可以将测试更改为:

private static bool HasOverlapTime(TimeSpan requestFrom, TimeSpan requestTo, TimeSpan detailFrom, TimeSpan detailTo)
{
    return (detailTo >= requestFrom) && (detailFrom <= requestTo);
}

最后用的这个方法已经在解决方案中了

        var overlappingRanges = ranges.Any(a =>
            ranges.Any(b => b != a && !(a.DateFrom > b.DateTo || b.DateFrom > a.DateTo)));
        if (!noSameDay)
        {
            return overlappingRanges;
        }
        return overlappingRanges || ranges.Any(c => c.DateTo == c.DateFrom);