2011-05-21 90 views
5

這讓我很困惑。我使用PetaPoco從數據庫中檢索一些值,然後遍歷它們並檢索值以分配給每個對象的屬性之一。修改foreach循環內的對象的屬性不起作用?

public IEnumerable<RetreaveIndex> FillResults(IEnumerable<RetreaveIndex> results) 
    { 
     //add the associated users 
     foreach (RetreaveIndex index in results) 
     { 
      index.AssociatedUsers = _registeredUserDao.GetUsersByIndex(index).ToList(); 
     } 
     return results; 
    } 

當我在foreach循環期間設置斷點時,正在設置AssociatedUsers屬性。 during foreach loop

但是,然後在循環結束的斷點,它沒有保存它? enter image description here

我很困惑,不應該是一個引用到正在修改的內存中的地方嗎?畢竟它是一個對象。我在這裏錯過了什麼?

回答

8
  1. 什麼是IEnumerable實現?它是否會返回該對象的副本?

  2. 是RetreaveIndex一個結構體,因此一個值類型?如果是這樣,那麼變量index將成爲副本。

+0

其對象(見原題的底部)。我查看了PetaPoco源代碼,看起來我調用的方法是Query (),它使用Yield Return來返回IENumerable。當我將我的電話改爲獲取()時,它返回一個它工作的List。也許我需要更多地閱讀收益率回報,我認爲這只是構建某種列表的語法糖,猜我錯了? – RodH257 2011-05-21 13:11:05

+1

yield return導致方法體被分割成一個巨大的case語句,該語句成爲新的IEnumerator類的MoveNext方法的主體。 – 2011-05-21 22:19:29

+0

我一直在IEnumerables多年的工作,令人驚訝的是,這是我第一次打這個......(這讓我完全困惑)乾杯! – FBryant87 2016-10-12 15:57:03

3

根據傳入的IEnumerable的實現方式,它沒有要求在下一次枚舉數據時返回與之前相同的對象。嘗試在foreach循環之前將IEnumerable轉換爲List並返回該insead。

1

project web site

查詢VS取

數據庫類有 檢索記錄查詢並獲取兩種方法。 除了 以外,它們幾乎完全相同,Fetch返回POCO的 的列表<>,而Query使用yield return返回 迭代結果,而不將 加載到內存中。

換句話說,Query每次都會從後備存儲中重新加載值,並且在枚舉後不會保留項目。當您在循環結束後再次查看某個項目時,該項目將從後備存儲中重新加載。

0

實際上,發生的事情是您錯誤地解釋了yield return語法的輸出。

發生了什麼事情是,當您遍歷從yield return返回的IEnumerable時,正在執行該代碼之後的代碼yield return正在執行。從技術上講,yield return正在做懶惰評估。所以在你的foreach循環的淨效果是,它調用的代碼,使IEnumerable項目,但無論如何很多項目在IEnumerable

從CodeProject下面的帖子做了解釋這種行爲的一個出色的工作: http://www.codeproject.com/Articles/38097/The-Mystery-Behind-Yield-Return.aspx