C#范例:列表的副作用我正在尝试了解更多关于副作用以及如何控制和应用它们的信息。在下面的航班等级列表中,我想设置满足条件的每个航班等级的属性:IEnumerablefResults=getResultsFromProvider();//设置所有直达航班描述fResults.Where(flight=>flight.NonStop).Select(flight=>flight.Description="FlyDirect!");在这个表达式中,我对我的列表有副作用。以我有限的知识,我知道前。“LINQ仅用于查询”和“列表上只有少数操作,分配或设置值不是其中之一”,“列表应该是不可变的”。您的LINQ代码不会“直接”违反您提到的准则,因为您没有修改列表本身;您只是在修改列表内容的某些属性。然而,推动这些准则的主要反对意见仍然存在:您不应使用LINQ修改数据(同样,您正在滥用Select来执行副作用)。不修改任何容易证明的数据是合理的。考虑以下代码片段:fResults.Where(flight=>flight.NonStop)你知道这会修改传单吗?许多维护程序员也不会,因为他们会在Where之后停止阅读-后面的代码显然没有副作用,因为它是一个查询,对吧?[吹毛求疵:当然,看到一个不保留返回值的查询是一个死的赠品,查询确实有副作用或应该删除的代码;无论如何,“出了点问题”。但是当它只是两行代码而不是页面上的页面时,它更容易说出来。作为一个合适的解决方案,我建议这样做:foreach(varxinfResults.Where(flight=>flight.NonStop)){x.Description="FlyDirect!";}写作和阅读很容易。您有两种实现LINQ方式的方法:显式foreach循环foreach(FlightfinfResults.Where(flight=>flight.NonStop))f.Description="FlyDirect!";使用ForEach运算符作为副作用:fResults.Where(flight=>flight.NonStop).ForEach(flight=>flight.Description="FlyDirect!");对于这样一个简单的任务,第一种方式非常重,第二种方式只能用于非常短的物体。现在,您可能会问自己,为什么LINQ堆栈中没有ForEach运算符。很简单——LINQ应该是一种表达查询操作的函数式方式,这尤其意味着任何运算符都不应该有副作用。设计团队决定将ForEach运算符添加到ForEach堆栈,因为唯一的用途是它的副作用。ForEach运算符的通常实现如下:foreach(Tobjinsource)action(obj);这种方法的一个问题是它根本不起作用。查询是惰性的,这意味着它不会执行Select中的代码,直到您实际从查询中读取,而您永远不会这样做。您可以通过在查询末尾添加.ToList()来解决此问题,但代码仍在使用副作用并丢弃实际结果。您应该使用结果来执行更新://Setallnon-stopflightsdescriptionforeach(varflightinfResults.Where(flight=>flight.NonStop)){flight.Description="FlyDirect!";除了你需要以某种方式迭代它之外结束,就像在它上面调用Count()一样,它工作没有任何问题。从“风格”的角度来看,这并不好。人们不会期望迭代器会更改列表值/属性。IMO以下会更好:foreach(varxinfResults.Where(flight=>flight.NonStop)){x.Description="FlyDirect!";}代码的读者或维护者的意图更清楚。您应该将其分成两段代码,一段用于检索,一段用于设置值:varnonStopFlights=fResults.Where(f=>f.NonStop);foreach(varflightinnonStopFlights)flight.Description="FlyDirect!";或者,如果您真的讨厌foreach的外观,您可以尝试:varnonStopFlights=fResults.Where(f=>f.NonStop).ToList();//ForEach是List上的一种方法,可以在内部进行修改。nonStopFlights.ForEach(f=>f.Description="FlyDirect!");当我实际更改某些内容时,我喜欢使用foreach。像foreach(varflightinfResults.Where(f=>f.NonStop)){flight.Description="FlyDirect!";EricLippert还在他的文章中谈到了为什么LINQ没有ForEach辅助方法。但我们可以在这里更深入一点。我出于两个原因在哲学上反对提供这样的方法。第一个原因是这样做违反了所有其他序列运算符所基于的函数式编程原则。显然,调用这个方法的唯一目的就是产生副作用。以上就是C#学习教程:C#实例:榜单副作用分享的所有内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。涉及侵权,请点击维权联系管理员删除。如需转载请注明出处:
