【问题标题】:Shorten a DateTime condition check缩短 DateTime 条件检查
【发布时间】:2023-04-09 22:45:02
【问题描述】:
if ((DateTime.Now.DayOfWeek != DayOfWeek.Friday && DateTime.Now.DayOfWeek != DayOfWeek.Saturday) &&
((DateTime.Now.Hour >= 10 && DateTime.Now.Hour < 13) || (DateTime.Now.Hour >= 20 && DateTime.Now.Hour < 23)))

我必须缩短这个条件,有什么建议吗?

【问题讨论】:

  • 为什么必须这样做?篇幅不短,但切中要害。
  • ...但它的可读性不是很好,这对于更容易理解代码很重要
  • @MUG4N - 这就是 cmets 的用途,如果它那么糟糕,请将其分散到多行,我认为逻辑不能缩短
  • 您可以将DayOfWeek 检查减少到:(Int32)DateTime.Now.DayOfWeek &lt; 5。
  • @Sayse 我同意你的观点,你不能缩短逻辑,但你可以通过选择自解释名称的子方法来提高可读性。如果方法名称正确,则不需要 cmets。

标签: c# conditional-statements


【解决方案1】:

好吧,你可以构建一个扩展方法:

public static bool BoundsCheck(this DateTime d, int min, int max, int min2, int max2)
{
    return (d.DayOfWeek != DayOfWeek.Friday &&
        d.DayOfWeek != DayOfWeek.Saturday &&
        d.Hour >= min &&
        d.Hour < max) ||
        (d.Hour >= min2 && d.Hour < max2);
}

然后这样称呼它:

if (DateTime.Now.BoundsCheck(10, 13, 20, 23))...

【讨论】:

  • +1 用于扩展方法,但您的参数可以更清楚地命名。
  • @deltree,谢谢!而且我会购买它们可以更好地命名,但老实说,我什至不知道如何命名它们,因为我真的不知道 OP 在这里做什么。 :D
  • 也许这可以重构以接收日期时间范围列表,即星期五 10-13、星期五 20-23 等
  • @deltree,我不这么认为。整数是检查Hour 的边界
  • 实际上我认为您的逻辑与此处的 OP 不匹配,他们将日期与两个小时段作为选项进行检查。
【解决方案2】:

这个更短吗?也许吧,但在我看来更重要的是它更具可读性和可维护性:

var now = DateTime.Now;
var notAllowedDays = new[] { DayOfWeek.Friday, DayOfWeek.Saturday };
var allowedHours = Enumerable.Range(10, 3).Concat(Enumerable.Range(20, 3));
if(!notAllowedDays.Contains(now.DayOfWeek) && allowedHours.Contains(now.Hour))
{

} 

【讨论】:

  • 如果你不是 Linq 大师,我担心可读的部分会死掉:)
  • 这是一个合理的解决方案,但我个人更喜欢原来的条件。
  • 我更喜欢使用“now”变量,因为每次检查之间都经过纳秒,因此更准确。
  • @deltree:是的,Now 也是一个相对昂贵的“财产”。它甚至需要使用IO访问:stackoverflow.com/a/10900267/284240
  • 恕我直言,如果允许或不允许日期和时间,它的可读性和可理解性会更高。更少的思考:) 但这只是吹毛求疵。
【解决方案3】:

我认为没有任何合理的解决方案,但我想到了几个。为DateTime 和DayOfWeek 使用别名。另一种选择是将所有这些值分配给条件之前的变量。

所以你可以做类似的事情;

 string fri = DayOfWeek.Friday;
 string sat = DayOfWeek.Saturday;

然后在条件中使用那些。或者;

 using dt = DateTime;

那你可以dt.Now.DayOfWeek

我个人不建议做这些事情。你实际上并没有缩短条件,你只是在重构。如果你在一个班级中有很多这样的东西,那么可能值得权衡,否则可能不是。

编辑:Michael Perrenoud 提出的扩展方法建议是一个合理的解决方案,实际上效果很好。

【讨论】:

    【解决方案4】:

    您可以更改使用时间

    (DateTime.Now.Hour % 12) +1 >= 10 && (DateTime.Now.Hour % 12) +1 < 13
    

    也许即使没有第二次检查。

    我认为除了寻找其他方法(如其他答案)之外,您没有比这更多的改进

    更新 我测试了上述内容及其错误,但这更加虐待狂并且有效

    var check = (DateTime.Now.Hours - 10 % 12) % 10;
     var checkV = (DateTime.Now.Hours >= 10 && check < 3);
    

    测试代码

    for (int i = 0; i < 24; i++)
    {
        var check = (i - 10 % 12) % 10;
        bool checkV = (i >= 10 && check < 3);
        Console.WriteLine(i.ToString() + ": " + checkV.ToString());
     }
     Console.ReadKey();
    

    更新 2 完整的缩短代码

    if(   (int)DateTime.Now.DayOfWeek < 5 && 
               DateTime.Now.Hours >= 10 && 
             ((DateTime.Now.Hours - 10 % 12) % 10) < 3)
    

    【讨论】:

    • 我只是在这里检查我自己的逻辑。我觉得有点不对劲,哈哈
    • @deltree - 我是对的,是错的,所以我变得更加邪恶;)
    • 你是对的,它更邪恶。我不明白了。
    • @deltree - 确保小时 >= 10(下限检查),然后是魔鬼部分:(将小时数减去 10,将余数除以 12,并再次保留结果除以 10,对于 10-12 和 20-23,返回小于 3 的 0 1 或 2...我个人喜欢 OP 问题中的原始代码
    • @Sinros:我不知道混淆是你的目标;)顺便说一句,这被称为 codegolf,甚至还有一个 stackexchange 网站可以解决这类难题:codegolf.stackexchange.com
    【解决方案5】:
    if (!this.ItsPartyDay() && (this.ItsLunchTime() || this.ItsDinnerTime()))
    {
        ...
    }
    
    private bool ItsPartyDay()
    {
        return (Int32)DateTime.Now.DayOfWeek >= 5;
    }
    
    private bool ItsLunchTime()
    {
        return (DateTime.Now.Hour >= 10 && DateTime.Now.Hour < 13);
    }
    
    private bool ItsDinnerTime()
    {
        return (DateTime.Now.Hour >= 20 && DateTime.Now.Hour < 23);
    }
    

    【讨论】:

    • 这就是重构的乐趣所在。
    猜你喜欢
    • 1970-01-01
    • 2020-02-05
    • 2021-12-12
    • 2016-09-25
    • 1970-01-01
    • 2015-10-08
    • 2017-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多