views:

48

answers:

3

It might be a simple fix, but I can't for the life of me think of how to do this. I compute a bunch of StartDates and End Dates into a bunch of arrays of dates using this query:

this.Reserved = unit.Reservations.Where(r => r.Active.HasValue && r.Active.Value).SelectMany(r => Utilities.DateRangeToArray(r.StartDate, r.EndDate)).ToArray();

Utilities.DateRangeToArray() is defined as follows:

public static IEnumerable<DateTime> DateRangeToArray(DateTime start, DateTime end) {
    DateTime curDate = start;
    while (curDate <= end) {
        yield return curDate;
        curDate.AddDays(1);
    }
}

Is there a way to make this less memory intensive?

Thanks!

+7  A: 

Your code is broken - AddDays doesn't change the existing value, it returns a new value. You're ignoring that new value, thus creating an infinite loop.

Change your code to:

public static IEnumerable<DateTime> DateRangeToArray(DateTime start,
                                                     DateTime end) {
    DateTime curDate = start;
    while (curDate <= end) {
        yield return curDate;
        curDate = curDate.AddDays(1);
    }
}

Another hint: unit testing can help you find this sort of problem long before you try to use the method in a LINQ query. I'd also change the name, given that it's not returning an array.

Jon Skeet
That's too easy to miss... bring on immutable classes/declared side-effect free methods, where this could generate a warning that the statement has no effect.
mancaus
Funny is right after I had posted it I found it. But of course everyone had already answered too.
Jeremy
There is also this guy who blogged about generic ranges some time ago: http://msmvps.com/blogs/jon_skeet/archive/2008/01/26/immutability-and-inheritance.aspx.
Groo
A: 

You're sure you don't have any reservations where r.StartDate > r.EndDate, right? If you do, you'll get an infinite loop, I think.

Rohith
No, that's the only case where it *won't* create an infinite loop - because it won't go into the body of the `while` loop at all.
Jon Skeet
A: 

I assume the out of memory is when converting the result to the array. Two points:

  • The output will contain duplicate dates for overlapping reservations.
  • Perhaps Reserved should be a collection of date ranges (start,end) rather than containing every date?
mancaus