2009-08-21 61 views
0

我在嘗試填充GridView時遇到了一個行爲,我無法理解。考慮下面的代碼:修改其他對象時發生變化的對象的變量

DataTable table = GetStockMovement((int)ViewState[MOVEMENT_ID], false); 
MovedProducts = from DataRow row in table.Rows 
        select new Product() 
        { 
         ProductId = (int)row["ProductId"], 
         ProductNo = row["ProductNo"].ToString(), 
         Name = row["ProductName"].ToString(), 
         Quantity = OriginalProducts.ToList().Find(p => p.ProductId == (int)row["ProductId"]).Quantity, 
         QuantityDiff = (int)row["Change"]                 
        }; 

foreach (Product product in MovedProducts) 
{ 
    Console.WriteLine(product.ProductId + ": " + product.Quantity); 
} 
Console.WriteLine(); 
foreach (Product product in OriginalProducts) 
{ 
    product.Quantity -= 1000; 
} 


foreach (Product product in MovedProducts) 
{ 
    Console.WriteLine(product.ProductId + ": " + product.Quantity); 
} 

這樣做的輸出是這樣的:

1: 10 
2: 4 

1: -990 
2: -996 

Product.Quantity是int MovedProducts和OriginalProducts是存儲在ViewState中IEnumerables。

當我在OriginalProducts中更改時,爲什麼MovedProducts中的產品發生更改?他們不是存儲在不同地方的兩個完全不同的對象嗎?

如果我而不是使用LINQ表達:

List<FPRSProduct> completedProducts = new List<FPRSProduct>(); 
foreach (DataRow row in table.Rows) 
{ 
    Product tmp = new Product(); 
    tmp.ProductId = (int)row["ProductId"]; 
    tmp.ProductNo = row["ProductNo"].ToString(); 
    tmp.Name = row["ProductName"].ToString(); 
    tmp.Quantity = OriginalProducts.ToList().Find(p => p.ProductId == (int)row["ProductId"]).Quantity; 
    tmp.QuantityDiff = (int)row["Change"];                 
    completedProducts.Add(tmp); 
} 

一切工作,因爲我預料到,這是我之前和改變OriginalProducts的數量後得到相同的號碼。

回答

2

LINQ利用我們所說的延期執行。當你寫出一個linq查詢時,你實際上並沒有執行查詢定義的任務......你只是簡單地定義它。你的查詢定義的行爲在使用時執行......在你的情況下,在兩個foreach語句中執行。對於每個foreach,查詢都是TWICE執行的,所以即使數據被複制......它在兩個不同的時間點從源複製兩次。圍繞您的MovedProducts的第二個foreach檢索您的OriginalProducts中更新的數據,因爲執行查詢被推遲到實際執行第二個foreach。

注意代碼的鏈接查詢「選擇新的」條款在本重點線:

Quantity = OriginalProducts.ToList().Find(p => p.ProductId == (int)row["ProductId"]).Quantity, 

既然你更新的第一和第二的foreach之間OriginalProducts,即使你正在創建一個distinc,產品對象列表...由於查詢的處理被推遲,因此您對每個產品的上述行執行兩次。第一次是foreach,第二次是foreach。