Ryan L
Ryan L

Reputation: 31

Update a List's object using Linq

I would like to assign an object in a list using Linq, but I can't find how to do it. I tried this:

Items.Where(i => i.Code == line.Code).Single() = line;

But it seems I simply cannot give the statement an object. I can modify properties of those objects (Like this) :

Items.Where(i => i.Code == line.Code).Single().name = line.name;

But giving it the full item doesn't seem to be accepted. Is there a reason to prevent this / a way to assign my value to the compatible item ? Thank you for your answer.

Upvotes: 0

Views: 2425

Answers (5)

Vinod Kumar
Vinod Kumar

Reputation: 408

Will below linq address your requirement?

      items.Where(i => i.Code== line.code)?.ToList()?.ForEach(i => i.name= line.name);

Upvotes: 0

Prasad Telkikar
Prasad Telkikar

Reputation: 16079

From MSDN Documentation: Language Integrated Query

By using query syntax, you can perform filtering, ordering, and grouping operations on data sources with a minimum of code.

You can not perform assignment using LINQ, you need to use index to update particular record from the list

To update record you can try FindIndex()

int index = Items.FindIndex(x => x.Code == line.Code); //returns -1 if record not found
Items[index]?.Name = "Stackoverflow";

Upvotes: 3

Christos
Christos

Reputation: 53958

Think about what the Single method returns. It returns a reference to the object that much the predicate you pass in the Where method. Specifically, when there is only one item in the Items that pass the predicate in the Where method, you will get a reference to this object. If there are more than one items, you will get an exception and if there are no items you will get null. Let's think about the happy case, in which you will have only one item. In that case, essentially you try to assign to this reference a new object. This does not make any sense. On the other hand that you try afterwards, makes sense, holding the reference you can mutate its state.

Upvotes: 1

Marc Gravell
Marc Gravell

Reputation: 1064204

Single() is a method that returns a value. You can't usually assign to the return from an expression. It is ultimately no different to saying:

Math.Max(32, 42) = 14;

at which point, Max is going to say "um, no; I was telling you the answer - I wasn't expecting you to tell me".


In theory, what you want here is possible, but only in advanced scenarios involving ref-returns. LINQ does not deal with ref-returns.

Upvotes: 1

Yeldar Kurmangaliyev
Yeldar Kurmangaliyev

Reputation: 34244

You cannot replace the value in the list using LINQ, because LINQ is a projection of a collection.

You can get your item and then find it in the list using IndexOf:

var item = Items.Single(i => i.Code == line.Code);
int index = Items.IndexOf(item);
Items[index] = new Item(); // replace the value

However, this approach is far from optimal in terms of algorithmic complexity, because it has to read through your list multiple times.
You can try to read more on Dictionary to find, add or replace items by key (in your case, Code) efficiently.

Upvotes: 3

Related Questions