2

これは、デリゲートとラムダ式を使用して、指定された開始日と終了日から稼働日を取得する簡単なコードです。

私の友人は、プログラム全体を 1 行で書けると言っています。どうすればいいですか?

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

4 に答える 4

1

これはあなたの質問に答えないかもしれませんが、2 つの理由から、これを行うべきではないことを伝えることが非常に重要です。

  1. 読みやすいコードを書くことは非常に重要であり、既存のコードは可能な限り優れています。複雑なワンライナーは、読みにくくするだけでなく、デバッグを難しくします。全体的なメンテナンスは悪夢です。

  2. 計算後に値を返すのではなく、副作用をもたらすことを目指しています。つまり、あなたのデリゲートは を返しますvoid。ここでは、Linq スタイルのクエリは適していません。

そして2つの提案:

  1. 私はArrayListあなたのコードを見ました。.NET 2 以降、これを使用するのは犯罪です。これを参照してください。に変更すると、ヒーローとして歓迎されますList<T>。あなたの友人が頭が良いなら、衒学的なことをするのではなく、そのような基本的なことを手伝ってくれるはずです。

  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 + " ");
}
于 2013-11-02T08:36:30.070 に答える
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);
于 2013-11-02T07:48:21.743 に答える
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 + " "));
于 2013-11-02T07:51:40.433 に答える