【问题标题】:Simplest way of calculating the number of working days using delegates in c#?在 c# 中使用委托计算工作日数的最简单方法?
【发布时间】:2013-11-13 10:03:30
【问题描述】:

这是我的简单代码,我使用委托和 lambda 表达式从给定的开始日期和结束日期获取工作日。

我的朋友说他可以在一行中写出整个程序。我该怎么做?

public delegate void GetWorkingDays(DateTime x,DateTime y);
class Program
{
    static void Main(string[] args)
    {
        var dt1 = new DateTime(2012, 10, 3);
        var dt2 = new DateTime(2013, 10, 3);
        System.Collections.ArrayList l = new ArrayList();
        GetWorkingDays d = (d1, d2) =>
        {
            while (d1.Date < d2.Date) 
            {
                if(d1.DayOfWeek == DayOfWeek.Saturday)
                {
                    d1 = d1.AddDays(2);
                    Console.WriteLine();
                }
                else
                {
                   Console.Write(d1.Day + "  ");
                    d1 = d1.AddDays(1);
                }
            } 
        };
        d(dt1, dt2);
    }
};

【问题讨论】:

  • “我的朋友说他可以在一行中写出整个程序。”让他回答你的问题:)
  • 我是c#的初学者,所以我在这里发布我的问题,以便我可以学习新事物。
  • 首先,您选择使用委托而不是方法是有原因的吗?您在这里添加了不需要的开销。除非目的当然是学习与代表合作。
  • 他居然告诉我使用delegate可以写成一行,所以我就试了一下...
  • 我明白,但我想打印周六和周日不遵循的日子...

标签: c# delegates


【解决方案1】:

我看不出你怎么能在一行中做到这一点,因为它至少需要一行来定义委托和一行来调用委托。但这是获取工作日的日期并计算它们的一条线。

GetWorkingDays d = (dateFrom, dateTo) =>
        Enumerable
            .Range(0, (int)dateTo.Subtract(dateFrom).TotalDays + 1)
            .Select(x => dateFrom.AddDays(x))
            .Count(x => x.DayOfWeek != DayOfWeek.Saturday && x.DayOfWeek != DayOfWeek.Sunday);
Console.Writeline("Number of Weekdays is {0}",d(dateFrom, dateTo));

或者

 var days = Enumerable
            .Range(0, (int)d2.Subtract(d1).TotalDays + 1)
            .Select(x => d1.AddDays(x))
            .Count(x => x.DayOfWeek != DayOfWeek.Saturday && x.DayOfWeek != DayOfWeek.Sunday);

【讨论】:

  • 对于单个返回语句,您不需要花括号和返回语句。
【解决方案2】:

虽然这可能无法回答您的问题,但告诉您根本不应该这样做非常重要,原因有二。

  1. 编写可读的代码是非常非常重要的,你现有的代码是尽可能好。复杂的单行代码不仅会降低其可读性,还会使调试变得更加困难。整体维护是一场噩梦。

  2. 您的目标是带来副作用,而不是在一些计算后返回值。换句话说,您的代表返回void。 Linq 样式查询不是这里的方法。

还有两个建议:

  1. 我在您的代码中看到了ArrayList。从 .NET 2 开始使用它是犯罪行为。See this. 如果您将其更改为 List&lt;T&gt;,您将被称为英雄。如果你的朋友很聪明,他应该在这些基本的事情上帮助你,而不是迂腐。

  2. Get... 开头的名称对于不返回(获取)任何内容 (void) 的方法(或委托)来说不是一个好名称。我会称它为WorkingDaysPrinter 左右。


只是为了它,你的答案应该是这样的:

WorkingDaysPrinter p = (d1, d2) => Enumerable.Range(0, d2.Subtract(d1).Days)
                                             .Select(x => d1.AddDays(x))
                                             .Where((x, i) => i == 0 || x.DayOfWeek != DayOfWeek.Sunday)
                                             .ToList()
                                             .ForEach(x =>
                                              {
                                                  if (x.DayOfWeek == DayOfWeek.Saturday)
                                                      Console.WriteLine();
                                                  else
                                                      Console.Write(x.Day + " ");
                                              });

最好稍微单独编写查询然后运行单独的foreach

WorkingDaysPrinter p = (d1, d2) => 
{
    var query = Enumerable.Range(0, d2.Subtract(d1).Days)
                          .Select(x => d1.AddDays(x))
                          .Where((x, i) => i == 0 || x.DayOfWeek != DayOfWeek.Sunday);
    foreach (var day in query)
    {
        if (x.DayOfWeek == DayOfWeek.Saturday)
            Console.WriteLine();
        else
            Console.Write(x.Day + " ");
    });
}

从表面上看,我认为如果您的代表返回工作日列表会更好。比如:

public delegate IEnumerable<DateTime> WorkingDaysGetter(DateTime x, DateTime y);

WorkingDaysGetter g = (d1, d2) => Enumerable.Range(0, d2.Subtract(d1).Days)
                                            .Select(x => d1.AddDays(x))
                                            .Where(x => x.DayOfWeek != DayOfWeek.Saturday && x.DayOfWeek != DayOfWeek.Sunday);
foreach (var day in g(dt1, dt2))
{
    Console.Write(x.Day + " ");
}

【讨论】:

    【解决方案3】:
    var count = Enumerable
            .Range(1, (int)y.Subtract(x).TotalDays)
            .Select(x => to.AddDays(x))
            .Count(x => x.DayOfWeek != DayOfWeek.Saturday && x.DayOfWeek != DayOfWeek.Sunday);
    

    【讨论】:

    • 我的问题不是要数...但是在给定的两个日期之间,所有不属于周六和周日的日子。
    【解决方案4】:
    GetWorkingDays getWorkDays = (d1, d2) =>
        Enumerable.Range(1, (int)(dt2 - dt1).TotalDays)
            .Select(d => dt1.AddDays(d))
            .Where(d => d.DayOfWeek != DayOfWeek.Saturday && d.DayOfWeek != DayOfWeek.Sunday)
            .ToList()
            .ForEach(d => Console.Write(d.Day + " "));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-14
      • 1970-01-01
      • 1970-01-01
      • 2016-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多