Using LINQ to change values in collection

First off, this is not a good idea. See below for arguments against it.

It doesn't work. The property value is not changed. Why?

It doesn't work because Select() doesn't actually iterate through the collection until you enumerate it's results, and it requires an expression that evaluates to a value.

If you make your expression return a value, and add something that will fully evaluate the query, such as ToList(), to the end, then it will "work", ie:

myObjectCollection.Select(myObject => { myObject.MyProperty = newValue; return myObject;}).ToList();

That being said, ToList() has some disadvantages - mainly, it's doing a lot of extra work (to create a List<T>) that's not needed, which adds a large cost. Avoiding it would require enumerating the collection:

foreach(var obj in myObjectCollection.Select(myObject => { myObject.MyProperty = newValue; return myObject; })) 
{ }

Again, I wouldn't recommend this. At this point, the Select option is far uglier, more typing, etc. It's also a violation of the expectations involved with LINQ - LINQ is about querying, which suggests there shouldn't be side effects when using LINQ, and the entire purpose here is to create side effects.

But then, at this point, you're better off (with less typing) doing it the "clear" way:

foreach (var obj in myObjectCollection)
{
     obj.MyProperty = newValue;
}

This is shorter, very clear in its intent, and very clean.

Note that you can add a ForEach<T> extension method which performs an action on each object, but I would still recommend avoiding that. Eric Lippert wrote a great blog post about the subject that is worth a read: "foreach" vs "ForEach".

Tags:

Linq