2017-02-01 56 views
4

我試圖簡化我的問題,這個例子中,列表中的項目:更新在不工作

List<User> userList = new List<User>() 
       { 
        new User {IdUser = 1, Login = "Frank" }, 
        new User {IdUser = 2, Login = "Pat" }, 
        new User {IdUser = 3, Login = "Max" }, 
        new User {IdUser = 4, Login = "Paul" }, 
        new User {IdUser = 5, Login = "John" } 
       }; 

User newUser = new User() 
    { 
     IdUser = 3, 
     Login = "Chris" 
    }; 

var userToUpdate = userList.FirstOrDefault(r => r.IdUser == 3); 
userToUpdate = newUser; 

爲什麼userList不包含該程序的結束時的值Login = "Chris"?如何更新列表中的項目?

PS1:我不想更新Login價值,我想更新用戶對象

PS2:它說,在這個link該FirstOrDefault選擇一個集合中的項目,但不「解鎖「或」克隆「它。即它是同一個實例。 所以,如果你修改一個屬性,你修改了原始實例。

我很困惑!

+1

'userToUpdate'是一個局部變量。用新用戶替換分配的用戶。所以變量變化,但不是與該變量無關的列表。如果你想修改列表使用:'int ix = userList.FindIndex(u => u.IdUser == 3); if(ix> = 0)userList [ix] = newUser;' –

回答

5

這樣做:

var userToUpdate = userList.FirstOrDefault(r => r.IdUser == 3); 

你得到的參考指向需要用戶副本。所以,有兩個不同的參考文獻指向這個用戶:userToUpdate和參考userList

當您將newUser指定爲userToUpdate時,您將有一個列表中的參考仍指向舊用戶,並且您將獲得指向newUser的參考userToUpdate

要更新的用戶,你應該做這樣的事情:

var index = userList.FindIndex(r => r.IdUser == 3); 

if (index != -1) 
{ 
    userList[index].Id = newUser.Id, 
    //set all other properties from newUser 
} 

OR

簡單的方法:

var index = userList.FindIndex(r => r.IdUser == 3); 

if (index != -1) 
{ 
    userList[index] = newUser;   
} 
+0

如何管理更新整個用戶對象? –

+3

'userList [index] = newUser'也可以工作 – stuartd

+0

@stuartd,我已經編輯了我的答案 –

0

因爲這裏

var userToUpdate = userList.FirstOrDefault(r => r.IdUser == 3); 

你得到一個參考而不是實際參考的副本。

+0

以及如何管理更新用戶對象? –

3

這樣做的原因有對象的方式是做存儲並在內存中引用。當您將User對象初始添加到集合時,集合將存儲對這些對象中的每一個的引用。

然後在這一行:

var userToUpdate = userList.FirstOrDefault(r => r.IdUser == 3); 

您正在創建參照其是在列表中從上方的對象之一。但是,您然後通過將newUser分配給該參考覆蓋userToUpdate = newUser;。對IdUser值爲3的原始用戶的引用在列表中仍保持不變。您需要用新元素替換列表中的元素:

int toReplaceIndex = userList.FindIndex(r => r.IdUser == 3); 

if (toReplaceIndex == -1) 
{ 
    userList[toReplaceIndex] = newUser; 
} 
else 
{ 
    // do whatever you want when the user ID being replaced doesn't exist. 
} 
+0

是否有任何其他方式可以在不刪除和添加對象的情況下執行更新? –

+0

是的,看我的更新。 –

1

但是,您並未修改正在修改變量值的屬性。

嘗試添加:

var ind = userList.IndexOf(userToUpdate); 
userList[ind] = newUser; 
+0

沒想到這一點,我認爲它會爲我的情況工作 –

0

你所描述與不同的對象實例替換對象的實例在列表中,而不是更新的實例。你能夠做到這像這樣的東西:它

List<User> userList = new List<User>() 
    { 
     new User {IdUser = 1, Login = "Frank" }, 
     new User {IdUser = 2, Login = "Pat" }, 
     new User {IdUser = 3, Login = "Max" }, 
     new User {IdUser = 4, Login = "Paul" }, 
     new User {IdUser = 5, Login = "John" } 
    }; 

User newUser = new User() 
{ 
    IdUser = 3, 
    Login = "Chris" 
}; 

var foundUser = userList.FirstOrDefault(item => item.IdUser == newUser.IdUser); 
if(foundUser != null) 
    userList.Remove(foundUser) 
userList.Add(newUser); 
+0

它會工作,但你做2操作('刪除',然後'插入')而不是一個('更新') –

+0

正確的,因爲如果你想更新它將涉及從「新」項目中獲取每個字段/屬性值並將它們分配給現有項目的對應字段/屬性。一些你不想做的事情。您可以使用此線程中其他地方提到的索引方法進行賦值,但效果會相同。 – Theo

0

這樣的想法:

收藏是單元網格,讓我們說,郵局信箱,並在某處這些框包含object1之一。你不確定在哪個盒子裏,通過調用.FirstOrDefault你要求'其他人'去找到你的單元格。你描述了這個對象的外觀,在他完成之後,他向你提供關於對象存儲在哪個盒子裏的信息。 (引用指向物理內存中對象位置的指針)。

假設我們的userToUpdate是您筆記本中的第1頁,您記下了他告訴您的這些信息。然後你轉到下一頁(page2),它包含有關其他對象(newUser)的記錄。

下一步該做什麼?你回到前一頁,用第2頁中包含記錄的信息(第1頁)替換寫在那裏的內容:「對象在餐廳」。

然後你撕下頁面,把它給'另一個人'說'喲!我需要對object1進行一些更改,這裏是有地址的文件,它會幫助你找到它,去改變它' 。

猜猜接下來會發生什麼?他會去餐廳。