patrick
patrick

Reputation: 16949

Is there a way to set values in LINQ?

Is there a better way to do these assignments with LINQ?

IEnumerable<SideBarUnit> sulist1 = newlist.Where(c => c.StatusID == EmergencyCV.ID);
foreach (SideBarUnit su in sulist1) su.color = "Red";

Upvotes: 10

Views: 300

Answers (6)

JaredPar
JaredPar

Reputation: 754575

The simplest way is to define a foreach extension method which allows you to add it onto the end of a query of this sort. For example

public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action) {
  foreach (var cur in enumerable) {
    action(cur);
  }
}

...

usage:

newlist
  .Where(c => c.StatusID == EmergencyCV.ID)
  .ForEach(cur => cur.color = "Red");

Upvotes: 4

Daniel Pryden
Daniel Pryden

Reputation: 60947

No.

You can do such a thing, as the other answers here point out, but then you are no longer using LINQ.

Eric Lippert wrote an excellent blog post about this very subject, which I highly recommend you read. Here is an excerpt:

I am philosophically opposed to providing such a method, for two reasons.

The first reason is that doing so violates the functional programming principles that all the other sequence operators are based upon. Clearly the sole purpose of a call to this method is to cause side effects.

The purpose of an expression is to compute a value, not to cause a side effect.

...

The second reason is that doing so adds zero new representational power to the language. Doing this lets you rewrite this perfectly clear code:

foreach(Foo foo in foos){ statement involving foo; }

into this code:

foos.ForEach((Foo foo)=>{ statement involving foo; });

which uses almost exactly the same characters in slightly different order. And yet the second version is harder to understand, harder to debug, and introduces closure semantics, thereby potentially changing object lifetimes in subtle ways.

Upvotes: 8

sll
sll

Reputation: 62484

Using List.ForEach() method:

IEnumerable<SideBarUnit> sulist1 = 
   newlist.Where(c => c.StatusID == EmergencyCV.ID)
          .ToList()
          .ForEach(item => item.color = "Red");

PS: I know about Eric Lippert's article aboout ForEach() vs foreach, but anyway it is useful and I preffer it rather than for/foreach loops

EDIT: regarding question in comment about performance hits

Enumerable.ToList() implemented as

public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    return new List<TSource>(source);
}

so performance hit is a time to create a new List<>() instance.

MSDN says next for List<>(IEnumerable<>) ctor:

Initializes a new instance of the List class that contains elements copied from the specified collection and has sufficient capacity to accommodate the number of elements copied.

So there is would be a copy operation of all list

Upvotes: 4

vc 74
vc 74

Reputation: 38179

Linq is all about selecting, not updating. But you could use ToList and List's ForEach to update the elements:

newlist.Where(c => c.StatusID == EmergencyCV.ID).
  ToList().
  ForEach(su => su.color = "Red");

I'm not sure the readability is better though...

Upvotes: 4

Andy Rose
Andy Rose

Reputation: 16974

You could use an anonymous method in a Select statement:

var sulist1 = newlist.Where(c => c.StatusID == EmergencyCV.ID)
                     .Select(c => {
                                     c.color = "Red";
                                     return c;
                                  });

Upvotes: 1

Jan
Jan

Reputation: 16032

LINQs purpose is mainly to query/project/transform data.

You might want to use the ForEach extension method. But see this discussion for more detail.

Upvotes: 2

Related Questions