可为空的日期比较功能-最佳实践.至少查找三个日期

本文关键字:日期 查找 三个 比较 功能 最佳 | 更新日期: 2023-09-27 18:20:42

场景:比较以从给定的3个可为空的日期中查找

已经有效的解决方案:使用正常的三元运算符(?)对它们进行比较,但代码对于3个日期来说太长了,如果以后添加第四个日期,那么代码就会很糟糕。它看起来很难看,但很管用。

(firstdate == null
    ? ((seconddate == null
        ? (thirddate == null ? null : thirddate)
        : (thirddate == null ? seconddate : ((seconddate < thirddate) ? seconddate : thirddate))) == null
        ? null
        : (seconddate == null
            ? (thirddate == null ? null : thirddate)
            : (thirddate == null ? seconddate : ((seconddate < thirddate) ? seconddate : thirddate))))
    : ((seconddate == null
        ? (thirddate == null ? null : thirddate)
        : (thirddate == null ? seconddate : ((seconddate < thirddate) ? seconddate : thirddate))) == null
        ? firstdate
        : ((firstdate < result)
            ? firstdate
            : (seconddate == null
                ? (thirddate == null ? null : thirddate)
                : (thirddate == null ? seconddate : ((seconddate < thirddate) ? seconddate : thirddate))))))

以前有人解决过这个问题并为空日期工作吗?有人能用例子分享最佳实践吗?

谢谢。

可为空的日期比较功能-最佳实践.至少查找三个日期

ret = firstdate;
if (ret == null || (seconddate != null && seconddate < ret))
    ret = seconddate;
if (ret == null || (thirddate != null && thirddate < ret))
    ret = thirddate;
return ret;

Resharper在修复代码/消除冗余时帮助了很多

return (firstdate == null
    ? ((seconddate == null
        ? (thirddate)
        : (thirddate == null ? seconddate : ((seconddate < thirddate) ? seconddate : thirddate))))
    : ((seconddate == null
        ? (thirddate)
        : (thirddate == null ? seconddate : ((seconddate < thirddate) ? seconddate : thirddate))) == null
        ? firstdate
        : ((firstdate < result)
            ? firstdate
            : (seconddate == null
                ? (thirddate)
                : (thirddate == null ? seconddate : ((seconddate < thirddate) ? seconddate : thirddate))))));

因此,为了弄清楚代码的作用:

  1. 如果firstdate为null,则返回second&thirddate,如果两者都为null则为null
  2. 如果firstdate是而不是null,则返回firstdate;result,否则返回second&thirddate,或者如果两者都为null则为null

所以。。。

if (firstDate.HasValue && firstDate.Value < result)
    return firstDate;
var otherDates = new[] { seconddate, thirddate };
return otherDates.Min();

这是我通过艰苦的方式学到的。除非你迫切希望获得绝对的最后一点效率,否则永远不要手动编写多路比较代码。这不值得。

如果可能值数量的扩展是一个问题,那么手工编写内联比较是一个糟糕的答案,因为超过大约四个,代码就是意大利面条。

如果你有一个任意的值数组,并且你想要最小的值,你会很快找到一个例程。然而,因为它是一个固定的集合,所以有一种倾向是尝试编写一个更努力的特定解决方案。

创建一个日期数组。

然后选择最小值。

它们可以为null这一事实并不相关,也不会使问题复杂化——你只需在所有比较中使用GetValueOrDefault(DateTime.MaxValue),这样实际日期总是小于null。

两种快速解决方案:

/* 1. Sort the list and take the first */
DateTime?[] dates = {dt1, dt2, dt3, dt4};
dates.Sort (New NullableDateTimeComparer);
return dates(0);
/* Then later */    
public class NullableDateTimeComparer : IComparer<DateTime>
{
  public new int IComparer(DateTime x, DateTime y)
  {
    return DateTime.Compare(x.GetValueOrDefault(DateTime.MaxValue), .GetValueOrDefault(DateTime.MaxValue);
  }
}
/* 2. Write a custom function that takes the minimum if you must: */
DateTime?[] dates = {dt1, dt2, dt3, dt4};
return MinDate(dates);
/* Then Later */
static public DateTime? MinDate(DateTime?[] dates)
{
  DateTime? min;
  for (int i = 0; i < dates.Length; ++i)
    if (dates[i].GetValueOrDefault(DateTime.MaxValue) < min.GetValueOrDefault(DateTime.MaxValue))
      min = dates[i];
  return min;
}

你永远不必担心你是否会记得你是如何做到的,你甚至不必考虑如何将其扩展到更大的用例中,而且效率的损失太小,除了在最特殊的情况下,不必担心。