0

This question already has an answer here:

I am trying to add a SELECT ALL functionality to my grid with LINQ, but I get a compilation error.

List<Person_> PeopleUpdated = People.ToList().ForEach(a => a.SELECTED = true).ToList();

It says

Cannot implicitly convert type 'void' to 'System.Collections.Generic.List < LogoSapHrIntegration.frmXmlUpload.Person_>'

what am I doing wrong?


  • What's wrong with: foreach(var p in People) p.SELECTED = true;? - Rango
  • People is an IEnumerable? - Yuval Itzchakov
  • Are you tying to change each person's SELECTED field / property, or are you just trying to filter SELECTED people. If its the latter, its just .Where(a => a.SELECTED) - StuartLC
  • What is PeopleUpdated supposed to contain? - the list of all selected people, or the list of people that were updated to be selected (ie that weren't already selected). Or is it just a mistake? - Jon Egerton

4 답변


4

The List<T>.ForEach has no return value (ie void), so you can't run ToList() against that. (see MSDN)

ForEach a specific action for each item in the list (just like doing a real for loop).

In your case a simple for loop to select all is most efficient.

foreach (var person in People)
    person.Selected = true


  • It might be important to note that if OP wants to update all person in People a plain foreach loop is much simpler and more efficient. - Rango
  • @TimSchmelter: Agreed - although the mucky bit of that is ending up with the PeopleUpdated list at the same time. Think the OP wants this to be a one-liner, and I'm not sure it can be. - Jon Egerton
  • Isn't this a "one-liner": foreach(var p in People) p.SELECTED = true;? According to the title OP wants to update the original list and doesn't need to create a new one. - Rango
  • Guys, the thing is that it's not entirely clear what he wants to do - Leo
  • @Leo Why isn't it clear? It's very clear to me. The OP is iterating the collection to set Selected to true. - Yuval Itzchakov

1

List<T>.ForEach returns void (in your case, it changes your collection in place). ForEach takes an Action<T> and executes that on each item of your list.

See List(T).ForEach on MSDN


  • no idea who downvoted it - Leo

0

First of all, you can use a normal foreach loop:

foreach (var person in people)
{
   person.Selected = true;
}

Which is the simplest and cleanest.

If you really want to jump to hoops and use LINQ, you can use ConvertAll:

var list = new List<Person> { new Person(), new Person() };
var convertedPeople = list.ConvertAll(person => 
{
    person.Selected = true;
    return person;
});


  • I don't think he's trying to modify the list..."I am trying to add a SELECT ALL functionality to my grid" - Leo
  • @Leo Well, if you wanted to add a Select all functionality, wouldn't you want to set all Selected properties to true? - Yuval Itzchakov

0

The ForEeach method (which is not LINQ) runs an action on each item in the list, it's not used to filter out items from a list so it doesn't return a result.

Just run the method on each item; there is no result to assign:

People.ToList().ForEach(a => a.SELECTED = true);

If you wanted a new list of items where the property was changed, you would need to clone the items to make them separate from the originals:

List<Person_> PeopleUpdated = People.ToList().Select(a => {
  Person_ b = a.Clone();
  b.SELECTED = true;
  return b;
}).ToList();

(If the class doesn't support cloning, you would need to implement the Clone method (and preferably the IClonable interface).)


  • Why would you need to clone the items? - Magnus
  • @Magnus: You would need to do that if you want a new list with changed values. Otherwise the items in the original list would also be changed. - Guffa
  • I would think that is the point. - Magnus
  • @Magnus: Perhaps, perhaps not. In the original code there was a new list as the result, I added code to show what would be needed to create such a result. - Guffa

Linked


Related

Latest