I am trying to convert this code to linq:
foreach (var printer in printers) { if (printer.Installed) installedPrinters.Add(printer); } I am new to Linq and would appreciate pointers on how it works when iterating through a collection.
printers.Where(printer => printer.Installed) .ToList() .ForEach(printer => installedPrinters.Add(printer)); Note the need to call ToList() before ForEach (see Lambda Expression using Foreach Clause).
Also note that while this works, your original code is probably easier to read... LINQ is cool but don't feel obligated to use it for everything :)
.ForEach() (nor do I). 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 purpose of a statement is to cause a side effect.printer => installedPrinters.Add(printer) could be installedPrinters.Add.ForEach has a signiature of Action<Printer> which void Add(Printer printer) fulfills. It just passes the argument in the same way the lambada does. (I agree with your fist comment too btw, he should not be using ForEach)ForEach as @Scott commented. In addition, I assume installedPrinters.Add returns void. Sorry for my insufficient words.If you are just trying to create a new list, you could always just do:
var installedPrinters = printers.Where(p => p.Installed).ToList(); If you are adding to a list that may already have items in it, then you could try:
installedPrinters.AddRange(printers.Where(p => p.Installed)); Assuming your installedPrinters is actually a collection that supports AddRange such as List.
So first use a Where to filter the Installed==true, then run over them with ForEach:
printers.Where(p => p.Installed).ForEach(p => installedPrinters.Add(p));