在c#中使用委托计算工作日数的最简单方法?

时间:2013-11-02 07:05:29

标签: c# delegates

这是我的简单代码,我使用委托和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);
    }
};

4 个答案:

答案 0 :(得分:2)

我不知道你怎么能在一行中做到这一点,因为它需要一行来定义委托,而一行最少要调用delagate。但是,这是平日和计算日期的一条线。

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);

答案 1 :(得分:1)

虽然这可能无法解答您的问题,但告诉您完全不应该这样做是非常重要的,原因有两个。

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

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

  3. 还有两个建议:

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

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


    3. 只是为了它,你的答案将是:

      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 + " ");
      }
      

答案 2 :(得分:0)

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);

答案 3 :(得分:0)

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 + " "));