2016-07-05 87 views
0

我遇到了一個相當奇怪的問題。我正在迭代List類型,並在我的循環中將迭代器變量分配給另一個本地對象。現在改變該本地對象中的任何內容都會導致循環迭代的List中的更改。讓我使用代碼示例清除它。Foreach循環內部的計算會影響迭代列表值

var balances = DBHelperADO.Select("select * from Orders"); 
// balances is of type List<MyModel> 

foreach (var item in balances) 
{ 
    MyModel model = new MyModel(); 
    model = item; 
    var thisQty = details.Where(x => x.Code == item.Code).Sum(x => x.QTY); 

    // details is another List<MyModel> holding values from the GUI 

    model.BLNC = model.BLNC - thisQty; 
    model.VAL = (model.BLNC == 0) ? 0 : model.VAL - (thisQty * model.RATE); 
    model.TABLE = "Orders"; 
    toUpdate.Add(model); // toUpdate is a List<MyModel>      
} 

現在,我的理解是,迭代變量(在這種情況下,項目)是隻讀的,當我寫:

模型=項目;

:我將我項目值的副本。但是當我在模型對象上進行計算時,它會在餘額列表上導致相同的更改。

我不明白爲什麼它影響餘額清單。我正在執行局部範圍的模型對象的計算。那麼爲什麼這些反映在迭代列表(餘額)。

請幫我看看我做錯了什麼。

問候

回答

3

我假設餘額中元素的類型是類別類型而不是結構

那麼,什麼是存儲在itemmodel參考到該類的實例。當你指定model = item;時你不要複製這個實例,但是隻有參考來實例。

當您現在通過model.BLNC = ...訪問該實例的屬性時,您將更改原始實例的屬性。這與調用item.BLNC = ...

相同,因爲您覆蓋對該新實例的引用,所以起始行MyModel model = new MyModel()已過時。

爲了做一個真正的副本,你可以嘗試這樣

MyModel model = new MyModel 
{  
    BLNC = item.BLNC, 
    VAL = item.VAL, 
    TABLE = "Orders" 
    // ... copy further properties 
}; 

你也完全與LINQ Select聲明這樣改寫你的循環:

var toUpdate = balances.Select(item => 
    { 
     var thisQty = details.Where(x => x.Code == item.Code).Sum(x => x.QTY); 
     var blnc = item.BLNC - thisQty; 
     return new MyModel 
     { 
      BLNC = blnc, 
      VAL = (blnc == 0) ? 0 : item.VAL - (thisQty * item.RATE), 
      RATE = item.RATE, 
      TABLE = "Orders" 
     }; 
    }).ToList(); 

您可能需要將MyModel類的更多屬性從item複製到新實例。如果嵌套查詢存在問題,則可能需要使用balances.AsEnumerable()

+0

非常感謝。那LINQ選擇真的很優雅。 –

3

model = item;使得參考,不是複製

model.BLNC = model.BLNC - thisQty;更新參考,即它更新原始對象中的值。

toUpdate.Add(model);參考添加回您在原始列表中的原始對象到新列表。