【发布时间】:2014-09-02 17:44:45
【问题描述】:
我正在尝试将此代码转换为 linq:
foreach (var printer in printers)
{
if (printer.Installed)
installedPrinters.Add(printer);
}
我是 Linq 的新手,希望在迭代集合时获得有关它如何工作的指针。
【问题讨论】:
我正在尝试将此代码转换为 linq:
foreach (var printer in printers)
{
if (printer.Installed)
installedPrinters.Add(printer);
}
我是 Linq 的新手,希望在迭代集合时获得有关它如何工作的指针。
【问题讨论】:
printers.Where(printer => printer.Installed)
.ToList()
.ForEach(printer => installedPrinters.Add(printer));
注意需要在 ForEach 之前调用 ToList()(参见 Lambda Expression using Foreach Clause)。
还请注意,虽然这可行,但您的原始代码可能更易于阅读... LINQ 很酷,但不必将它用于所有事情 :)
【讨论】:
.ForEach()(我也没有)。第一个原因是这样做违反了所有其他序列运算符所基于的函数式编程原则。显然,调用此方法的唯一目的是引起副作用。表达式的目的是计算一个值,而不是产生副作用。声明的目的是产生副作用。
printer => installedPrinters.Add(printer) 可以是 installedPrinters.Add。
ForEach 具有 Action<Printer> 的签名,void Add(Printer printer) 满足。它只是以与 lambada 相同的方式传递参数。 (顺便说一句,我也同意你的第一条评论,他不应该使用ForEach)
ForEach 传递。另外,我假设installedPrinters.Add 返回void。对不起,我的话不够。
如果您只是想创建一个新列表,您总是可以这样做:
var installedPrinters = printers.Where(p => p.Installed).ToList();
如果您要添加到可能已经包含项目的列表中,那么您可以尝试:
installedPrinters.AddRange(printers.Where(p => p.Installed));
假设你的installedPrinters实际上是一个支持AddRange的集合比如List。
【讨论】:
所以首先使用Where 过滤Installed==true,然后使用ForEach 遍历它们:
printers.Where(p => p.Installed).ForEach(p => installedPrinters.Add(p));
【讨论】:
foreach (var printer in printers.Where (p => p.Installed) { installedPrinters.Add(printer); }
【讨论】:
试试这个
printer.Where(x => x.Installed).ToList()
.ForEach(
p=>
{
installedPrinters.Add(p)
}
);
【讨论】: