代码之家  ›  专栏  ›  技术社区  ›  Lachlan

调用委托而不指定委托的参数

  •  0
  • Lachlan  · 技术社区  · 14 年前

    我希望重构两个类似的函数来消除重复:

    IEnumerable<TotalType> GetTotalForMonths(string id, DateTime lastTotalDate)
    {
        for (int i = 0; lastTotalDate.AddMonths(i + 1) <= DateTime.Now; i++)
        {
            var totalStartDate = new DateTime(lastTotalDate.AddMonths(i).Year, lastTotalDate.AddMonths(i).Month, 1);
            var totalEndDate = totalStartDate.AddMonths(1);
            var total = this.GetTotal(id, totalStartDate, totalEndDate);
            yield return new TotalType(id, total, new TimeInterval(totalStartDate, totalEndDate));
        }
    }
    

    另一个做了几天同样的事情。我希望通过一个代表来通用化特定的持续时间(天、月等)。我试过传球 Func<DateTime, DateTime> addTime ,除了我不想指定addtime的arg值外,它工作得很好。

    建议?

    3 回复  |  直到 14 年前
        1
  •  2
  •   LukeH    14 年前
    var byMonths = GetTotal(123, yourDate, (d, i) => d.AddMonths(i));
    
    var byDays = GetTotal(456, anotherDate, (d, i) => d.AddDays(i));
    
    // ...
    
    IEnumerable<TotalType> GetTotal(
        string id, DateTime lastTotalDate, Func<DateTime, int, DateTime> adder)
    {
        for (int i = 0; adder(lastTotalDate, i + 1) <= DateTime.Now; i++)
        {
            var temp = adder(lastTotalDate, i);
            var totalStartDate = new DateTime(temp.Year, temp.Month, 1);
            var totalEndDate = adder(totalStartDate, 1);
            var total = this.GetTotal(id, totalStartDate, totalEndDate);
            var interval = new TimeInterval(totalStartDate, totalEndDate);
    
            yield return new TotalType(id, total, interval);
        }
    }
    
        2
  •  2
  •   Mehrdad Afshari    14 年前

    我不确定我是否理解你的问题,但如果你想通过 AddMonth 方法作为参数,在不指定Receiver对象的情况下,可以构造lambda:

    GetTotal(id, lastDate, (dt, num) => dt.AddMonth(num))
    

    调用“genericized”函数。

    您需要将函数声明为:

    IEnumerable<TotalType> GetTotal(string id, DateTime lastTotalDate,
       Func<DateTime, int, DateTime> adder)
    
        3
  •  0
  •   Community Rick James    7 年前

    你想做的就是“讨价还价”。我有一个在vb.net中使用的模式;我不确定它是最好的模式,但是它应该能够适应C而不会有太多麻烦。请注意,虽然使用lambda表达式会限制您使用“编辑并继续”的能力,但使用curry工厂不会造成这种限制。

    以下是我的问题的链接: What is the best pattern to curry delegate parameters (using .NET 2.0 or later)?

    这应该很好地翻译成c;任何时候你看到以“(of)”开头的括号,用尖括号替换它们;“byref foo as bar”和“dim foo as bar”都变成“bar foo”。