Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ+Lambda与标准索引器+foreach相比,即使MS和Lippert说,索引器也更好。在这种情况下呢?_C#_Linq_Foreach - Fatal编程技术网

C# LINQ+Lambda与标准索引器+foreach相比,即使MS和Lippert说,索引器也更好。在这种情况下呢?

C# LINQ+Lambda与标准索引器+foreach相比,即使MS和Lippert说,索引器也更好。在这种情况下呢?,c#,linq,foreach,C#,Linq,Foreach,我在研究4个监控类/方法之间的主要区别,比如async/await、Task、BackgroundWorker和Thread,所以我创建了一些控件,它们只与这4个方法/对象交互。 我还想同时深入研究LINQ/LAMBDA,并设法编写了一些成功的LINQ语句,例如这样的语句 (from t in tabControlOutput.TabPages.Cast<TabPage>() from c in t.Control

我在研究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的评论

除此之外,我知道LINQ为标准操作提供了一些开销,这些开销可以由标准指令而不是LINQ发出,开销问题似乎是MS的特殊原因,为什么坚持使用标准LINQ较少处理,但E.Lippert还有一些其他论点,特别是指ForEach

有些说法似乎让我感到困惑:

。。。。目的 表达式用于计算值,而不是产生副作用。这个 陈述的目的是引起副作用

我从未在任何编程书籍、最佳实践或其他任何东西中听说/读到过这一点。根据我的经验,副作用这个词通常带有一种随意的负面味道,而不是一个自愿实现的目标

有谁能澄清E.Lippert的这句话吗

此外,E.Lippert指出,有些两行似乎更难维持,我不会接受。好吧,这可能是基于观点的

但是,关于我的代码,我可以看到唯一丑陋的是演员阵容

那么,是否会有一个合理的理由不是基于观点,而是纯技术术语、论点、限制性陈述、原则,可读性也属于它们,为什么我的台词应该或不应该被传统的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是什么有点吹毛求疵

我是林克。语言集成查询。你在质疑。阅读

(from t in tabControlOutput.TabPages.Cast<TabPage>()
 from c in t.Controls.OfType<WebBrowser>()
 select c).ToList()
只需要调用.ToList,就可以调用所述类的.ForEach方法。如果只对LINQ的结果使用普通foreach,效率会更高


因此,您的代码从一开始就不是纯LINQ,它实际上是在处理数据,这可能会让认为它是纯LINQ的普通读者感到惊讶,从而违反了规则。最后但并非最不重要的一点是,它的效率低于foreach替代方案。

不,总体而言,它肯定是基于意见的。在您的特定情况下,您的代码不必要地低效,因为您正在调用ToList,如果您只是对结果进行迭代,这是可以避免的,但是对于已经有列表的情况,存在基于意见的论点。甚至,如果我们尽可能地坚持纯粹的技术术语/论据,即不产生副作用,这意味着预期任何状态都不应发生变异。您的LINQ表达式,直到您调用.ToList的地方,应该可以多次调用,而不改变结果,就像一个纯函数一样。LINQ也是懒惰的,所以表达式列表。其中i=>i>5实际上本身什么都不做,直到您对它求值为止。所以ForEach扩展肯定有不同的行为。好吧,对我来说这已经是一个很好的论点了。当我可以保存额外的var时,为什么我要将该结果放入var查询,该查询将返回一个列表?谁会做这样的事?为什么?所以,乔恩,你说,效率低下。。。就性能而言,因为我隐式地使用列表,而不是在后面迭代。。你的意思是,这会降低性能吗?@icbytes:如果对每个循环使用一个普通的,那么根本不必有一个列表。您只需迭代惰性枚举器。LINQ表达式的结果是一个表达式树,而不是一个列表,因此查询变量只需引用表达式树.THX即可,这是一个非常好的答案,没有任何意见。
.ForEach(c => c.Navigate(Constants.BlankUrl));