Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update an item in the list not working

Tags:

c#

linq

I tried to simplify my problem with this example:

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;

why userList does not contain the value Login = "Chris" by the end of this program? How is it possible to update an item within a list?

PS1: I don't want to update the Login value, I want to update the User Object

PS2: It says in this link that FirstOrDefault selects an item in a collection, but does not "detatch" or "clone" it. I.e. it is the same instance. So if you modify a property you modify the original instance.

I am confused!

like image 837
Mehdi Souregi Avatar asked Feb 01 '17 15:02

Mehdi Souregi


2 Answers

Doing this:

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

you get copy of reference that points to needed user. So, there are two different references pointing to this user: userToUpdate and reference inside userList.

When you assign newUser to userToUpdate you have one reference from list still pointing to the old user and you get reference userToUpdate pointing to newUser.

To update user you should do something like this:

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

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

OR

simpler way:

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

if (index != -1)
{
    userList[index] = newUser;        
}
like image 105
Roman Doskoch Avatar answered Nov 19 '22 05:11

Roman Doskoch


The reason for this has to do with the way objects are stored and referenced in memory. When you are adding your User objects initially to the collection, the collection is storing references to each of those objects.

Then on this line:

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

You are creating a second reference to one of the objects which is in the list from above. However, you then overwrite that reference by assigning newUser to it: userToUpdate = newUser;. The reference to the original user whose IdUser value is 3 still remains intact in the list. You need to replace that element in the list with the new element:

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.
}
like image 4
rory.ap Avatar answered Nov 19 '22 05:11

rory.ap