2010-09-22 39 views
1

這可能是一個簡單的修復,但我不能爲我的生活考慮如何做到這一點。我計算了一堆StartDates和結束日期的成一束使用此查詢日期的數組:當計算日期範圍時拋出System.OutOfMemoryException

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

Utilities.DateRangeToArray()的定義如下:

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

有沒有一種方法,使這少了內存密集?

謝謝!

回答

7

您的代碼已損壞 - AddDays不會更改現有值,它會返回一個新值。你忽略了這個新值,從而造成無限循環。

你的代碼更改爲:

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

另一個提示:單元測試可以幫助您嘗試使用的方法,在LINQ查詢很久以前你會發現這類問題。因爲它沒有返回數組,所以我還要更改名稱。

+0

這太容易錯過了...帶來不可變的類/聲明的副作用自由方法,其中這可能會產生警告,說明語句沒有效果。 – mancaus 2010-09-22 08:59:36

+0

有趣的是,我發佈後,我發現它。但當然每個人都已經回答了。 – 2010-09-22 09:00:17

+0

還有一個人前段時間曾經在博客上介紹過泛型範圍:http://msmvps.com/blogs/jon_skeet/archive/2008/01/26/immutability-and-inheritance.aspx。 – Groo 2010-09-22 09:02:37

0

你確定你沒有任何保留的地方r.StartDate> r.EndDate,對不對?如果你這樣做,我想你會得到一個無限循環。

+1

不,這是它*不會創建無限循環的唯一情況 - 因爲它根本不會進入'while循環體。 – 2010-09-22 08:56:04

0

我假設內存不足時將結果轉換爲數組。兩點:

  • 輸出將包含重疊保留的重複日期。
  • 也許保留應該是日期範圍(開始,結束)的集合,而不是包含每個日期?