简体   繁体   中英

C# LINQ update item List<string>

I have problem with updating a single item under List<string> that matches a different string using LINQ. Let's say that I have a list of names and I want to check if name "John" already exists in my list. If yes, then replace "John" with "Anna".

Here is what I do:

var sItem = myList.First(n=> n == "John"); //I am 100% sure that John exists, that\s why I use .First
sItem = "Anna";

This is how it should work, but when I check my List (myList) after the process, the original item is still there (I can still see John, instead of Anna). I also tried to implement INotifyChanged on the List, but still no result.

What am I doing wrong?

If you need to update, use FindIndex :

int index = myList.FindIndex(n => n == "John");
myList[index] = "Anna";

You are assigning the result of linq query to a string variable. That is not the element of list but a variable that is also referencing the element of that list. Changing the value of variable sItem will define a new string that will be referenced by the sItem and the item in the list remains unchanged.

You can use FindIndex to get the index of element in the array and use it to refer to list element.

int index = myList.FindIndex(n => n == "John");
myList[index] = "Anna";

Searches for an element that matches the conditions defined by the specified predicate, and returns the zero-based index of the first occurrence within the entire List.

Edit

When one string variable is assigned to other. They both would be referencing the same string but when you assign a different string to second variable for instance then they both referencing different strings. See the following example from answer of Eric Lippert.

a----------------------Hello

Then you say that "b = a", which means attach another piece of string to the same thing that a is attached to :

a----------------------Hello
                      /
b---------------------

Then you say "now attach b to Hi"

a----------------------Hello

b----------------------Hi
int index = strList.FindIndex(n => n == "John");
if (index != -1)
{
    strList[index] = "Anna";
}

This will ensure that if "John" does not exist in the list, the program does not crash.

It should work for you

List<string> list = new List<string>(); 

list.Add("Gandarez");
list.Add("Carlos");

var search = list.FirstOrDefault(l => l == "Carlos");

if (search != null)
{
    var index = list.IndexOf("Carlos");
    list.RemoveAt(index);
    list.Insert(index, "Test");
}
int sItem = myList.FindIndex(x => x == "John");
myList[sItem] = "Anna";
static void Main (string [] args)
    {
      List <int> list = new List <int> ();
      list.Add (1);
      list.Add (2);
      list.Add (3);      

list = list.Select (x => x + 6) .ToList ();    

}

The problem you are seeing is that System.String , while actually a reference type, acts like a value type. So, when you assign a new value to sItem you are replacing it, not changing it.

If you were using a true reference type, what you tried could have worked:

List<Person> myList = ....;
var sItem = myList.First(p=> p.Name == "John");
sItem.Name = "Anna";

(Assigning -- sItem = new Person("Anna"); -- would still fail the same way,)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM