LINQ+Lambda vs.标准索引器+foreach——即使MS和Lippert都说,索引器更好.在这种情况下
本文关键字:索引 都说 这种情况下 更好 Lippert 即使 标准 vs +foreach LINQ+Lambda MS | 更新日期: 2023-09-27 17:55:06
我正在玩4个监视器类/方法之间的主要差异,如async/await, Task, BackgroundWorker和Thread),所以我创建了一些控件,它只是与这4种方法/对象进行交互。与此同时,我也想深入研究LINQ/LAMBDA,并设法编写了一些成功的LINQ语句,例如:
(from t in tabControlOutput.TabPages.Cast<TabPage>()
from c in t.Controls.OfType<WebBrowser>()
select c).ToList().ForEach(c => c.Navigate(Constants.BlankUrl));
当然我在发布这个问题之前正在寻找,我发现了一些像这样的好信息
第一次联系
重定向到Eric Lippert的评论
foreach vs foreach
除此之外,我知道LINQ为标准操作提供了一些开销,这些开销可以由标准指令而不是LINQ发出,开销问题似乎是MS为什么坚持标准的LINQ-less处理的特殊原因,但是e.l lippert有一些其他的论点,特别是提到ForEach。
有一些语句似乎把我弄糊涂了:
…的目的表达式是用来计算值的,而不是产生副作用的。的语句的目的是引起副作用。
我从来没有在任何编程书、最佳实践或其他什么书中听说过或读到过这个。根据一般的(和我的)经验,"副作用"这个词通常带有武断的负面意味,而不是一个自愿实现的目标。
谁能澄清一下e.l lippert的这句话?
此外,e.l lippert指出,有两行似乎更难维护,我不会接受(好吧,这可能是基于个人意见)。
但是,对于我的这段代码,我可以看到唯一"丑陋"的地方是"Cast"。
那么,是否有一个合理的理由(不是基于观点,而是纯粹的技术术语,论证,限制性陈述,原则(可读性也属于它们),为什么我的行应该或不应该被传统的foreach,甚至反射取代呢?
编辑:我修改了代码,去掉了之前的代码行,做了注释并添加了这些代码行。请随意评论:
// ---> NOT RECOMMENDED APPROACH: Because LINQ is more designed to query, but at the end
// There is a modification of the queried objects, which
// Is not real LINQ, but a mix.
// And it violates the principles of least astonishment/surprise
// Changed to
var qresult = (from t in tabControlOutput.TabPages.Cast<TabPage>()
from c in t.Controls.OfType<WebBrowser>()
select c);
foreach (var tmp in qresult)
{
tmp.Navigate(Constants.BlankUrl);
}
首先,让我对LINQ是什么有点挑剔。
这是LINQ。语言集成查询。你正在查询。阅读。
(from t in tabControlOutput.TabPages.Cast<TabPage>()
from c in t.Controls.OfType<WebBrowser>()
select c).ToList()
下面是而不是。从技术上讲,它不是LINQ(一组扩展方法),而是List<T>
类的普通类成员。从哲学上讲,这不是质疑。你正在操作数据:
.ForEach(c => c.Navigate(Constants.BlankUrl));
对.ToList()
的调用只需要这样您就可以调用所述类的.ForEach
方法。如果您对LINQ的结果只使用普通的foreach
,则会更有效。
所以你的行从一开始就不是普通的LINQ,它实际上是在操纵数据,这可能会让不经意的读者感到惊讶,他们认为这是普通的LINQ,因此违反了最小惊喜原则。最后但并非最不重要的是,它比foreach
替代方案效率低。