tags:

views:

47

answers:

2

I have two similar functions I hope to refactor to remove duplication:

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

The other does the same thing for days. I hope to pass in a delegate to generic-ize the particular duration (days, months, etc). I tried passing in Func<DateTime, DateTime> addTime, which works well, except that I don't want to specify addTime's arg value.

Suggestions?

+2  A: 

I'm not sure if I understood your question correctly, but if you want to pass AddMonth method as an argument, without specifying the receiver object, you can construct a lambda:

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

to call the "genericized" function.

You need to declare the function as:

IEnumerable<TotalType> GetTotal(string id, DateTime lastTotalDate,
   Func<DateTime, int, DateTime> adder)
Mehrdad Afshari
+2  A: 
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);
    }
}
LukeH