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

时间:2015-11-06 03:33:41

标签: c# nullable

场景:比较给定的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))))))

之前有没有人解决这个问题,并且可以在可以约会的日期工作?有人可以通过示例分享最佳实践吗?

谢谢。

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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,则返回最小的第二个&amp; thirddate,如果两者都为null,则为null
  2. 如果firstdate null,则返回firstdate如果firstdate&lt;结果,否则返回最小的秒和&amp; thirddate,如果两者都为null,则返回null。
  3. 因此...

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

答案 2 :(得分:-1)

我很难学到这一点。除非你急需最后一点效率,否则不要手工编写多路比较。这不值得。

如果扩展可能值的数量是一个问题,那么手写内联比较是一个不好的答案,超过大约四个代码是意大利面。

如果你有一个任意数组的值,并且你想要最小的值,那么你就可以立即找到一个能够找到它的例程。然而,因为它是一个固定的集合,所以有一种倾向,试图编写一个更加努力的特定解决方案。

创建日期数组。

然后选择最小值。

它们可以为空的事实并不重要,并且不会使问题复杂化 - 您只需在所有比较中使用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;
}

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