1

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?

Mahmoud Gamal
  • 78,257
  • 17
  • 139
  • 164
Arif YILMAZ
  • 5,754
  • 26
  • 104
  • 189
  • 2
    What's wrong with: `foreach(var p in People) p.SELECTED = true;`? – Tim Schmelter Apr 30 '15 at 08:31
  • `People` is an `IEnumerable`? – Yuval Itzchakov Apr 30 '15 at 08:31
  • 1
    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 Apr 30 '15 at 08:38
  • 1
    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 Apr 30 '15 at 08:41

4 Answers4

5

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
Jon Egerton
  • 40,401
  • 11
  • 97
  • 129
  • 1
    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. – Tim Schmelter Apr 30 '15 at 08:35
  • @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 Apr 30 '15 at 08:36
  • 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. – Tim Schmelter Apr 30 '15 at 08:37
  • Guys, the thing is that it's not entirely clear what he wants to do – Leo Apr 30 '15 at 08:39
  • @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 Apr 30 '15 at 08:40
  • i've asked the question in the main comments of what `PeopleUpdated` is supposed to end up with. – Jon Egerton Apr 30 '15 at 08:41
2

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

germi
  • 4,628
  • 1
  • 21
  • 38
1

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).)

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • Why would you need to clone the items? – Magnus Apr 30 '15 at 08:44
  • @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 Apr 30 '15 at 09:04
  • I would think that is the point. – Magnus Apr 30 '15 at 09:08
  • @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 Apr 30 '15 at 09:13
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;
});
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
  • I don't think he's trying to modify the list..."I am trying to add a SELECT ALL functionality to my grid" – Leo Apr 30 '15 at 08:41
  • @Leo Well, if you wanted to add a `Select all` functionality, wouldn't you want to *set* all `Selected` properties to `true`? – Yuval Itzchakov Apr 30 '15 at 08:42