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+Lambda vs.标准索引器+foreach——即使MS和Lippert都说,索引器更好.在这种情况下

首先,让我对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替代方案效率低。