在Visual Studio中,Re-Sharper一直建议我将for循环转换为linq表达式,但这是什么原因?
哪个更快?
以下是一些示例循环,其中resharper建议使用linq转换:
foreach (XmlNode legendEntryNode in _legendEntryNodes)
{
var xmlElement = legendEntryNode["FeatureType"];
if (xmlElement == null || !xmlElement.InnerText.Equals(featuretype)) continue;
var xmlNodeList = legendEntryNode.SelectNodes("Themes/Theme");
if (xmlNodeList != null)
foreach (XmlNode themeNode in xmlNodeList)
{
var element = themeNode["Value"];
if (element == null || !element.InnerText.Equals(v)) continue;
var xmlElement1 = themeNode["Icon"];
if (xmlElement1 != null)
{
string iconname = "<ms:ICON>" + xmlElement1.InnerText + "</ms:ICON>";
var element1 = themeNode["Highlight"];
if (element1 != null)
{
string highlightname = "<ms:HIGHLIGHT>" + element1.InnerText + "</ms:HIGHLIGHT>";
gml = gml.Insert(c, iconname + highlightname);
c += (iconname.Length + highlightname.Length);
}
}
break;
}
}
这个更简单的例子:
for (int i = 0; i < getPointsRequest.Attribs.Length; i++)
{
string attribName = getPointsRequest.Attribs[i].AttributeName;
if (!String.IsNullOrEmpty(attribName))
{
sqlQuery += "<ms:" + attribName + ">||\"" + attribName + "\"||</ms:" + attribName + ">";
}
}
答案 0 :(得分:36)
速度通常与代码的大部分内容无关 - 您应该使用最简单的方式编写代码,然后对其进行测量以确保足够快。
如果你的for循环真的只是查询,那么LINQ 绝对是一个结束更可读代码的好方法。它不是普遍适用的,但它应该至少牢记。
通常可以将for循环转换为懒惰评估的查询,然后是foreach循环,对查询返回的每个值执行一些操作。这可以帮助区分这两个方面,让您在阅读代码时一次关注一个方面。将LINQ查询保留为查询非常重要,而不是在其中使用副作用 - 它的设计目的是提供一种功能性方法,它实际上不会与副作用混合得很好。
如果你有一些具体的例子,我们可以提供更多关于转换为使用LINQ哪些循环有意义的意见,哪些不会。
答案 1 :(得分:15)
没有性能提升,但有一些好处
有关详细信息,请参阅:
希望这会对你有所帮助。
答案 2 :(得分:4)
速度可能没有差别,但是使用Linq通常会产生更严格的代码。 这并不是说你应该总是接受R#的转换为Linq表达式的建议。有时复杂但可理解的foreach循环被转换为有效但不易理解的Linq表达式。
答案 3 :(得分:3)
一般来说,ReSharper的建议只是建议而非警告。因此,只有你自己决定走哪条路:LINQ或foreach 我有同样的问题,建议“使用'var'”。只有当我认为读者能够更好地阅读声明时,我才会点击该建议 在编写代码时,可读性是我的首要任务之一。
答案 4 :(得分:3)
我会说有时候不转换的原因。 ReSharper不提供将LINQ表达式(返回)转换为for循环的重构可能不太令人钦佩。我有几次将一个循环转换为一个表达式,然后又想在循环中放入一些进一步的动作(通常是调试动作);我必须手工转换它们。
我会警告不要在没有充分理由的情况下转换for循环。通常它确实没有提高可读性,并且没有任何其他强有力的理由去做(正如其他人正确指出的那样,大多数循环不是速度关键的。)
我认为一些for循环比LINQ等价物更易读,因为它们可以直观地将循环的动作分解为一口大小的碎片。我会说它往往是小循环(三行或四行),通过将它们变成一行中的表达式而得到最大改善。
[对不起这篇文章主要是意见,但可读性有点主观。没有拖钓!]
答案 5 :(得分:2)
Hi Linq实际上是在内部调用for循环。我想Linq表达式通常更易于阅读/维护。如果你真的关心性能,那么两者之间有一个很好的比较:http://geekswithblogs.net/BlackRabbitCoder/archive/2010/04/23/c-linq-vs-foreach---round-1.aspx
答案 6 :(得分:0)
作为其他人的参考,这里是一个for循环的示例和Resharper建议的for循环
for (int x = 0; x < grid.Length; x++)
{
var intCount = grid[x].Select((a, b) => new {Value = a, Index = b})
.GroupBy(y => y.Value)
.Where(y => y.Count() > 1).Select(item => item.Key).ToArray();
if (intCount.Count() > 1)
return false;
}
为了解释这段代码,这个for循环将获得一个数组上的所有重复项。获取所有重复项后,检查项目数是否大于1,然后返回false。
这是LINQ中建议的for循环:
return grid.Select(t => t.Select((a, b) => new {Value = a, Index = b}).
GroupBy(y => y.Value).Where(y => y.Count() > 1).
Select(item => item.Key).ToArray()).All(intCount => intCount.Count() <= 1);
可能没有性能提升,但正如您从示例中看到的那样,LINQ查询更干净,易于阅读,线条较少(在这种情况下,只有一行代码,我只是在粘贴后对其进行了调整)这里也很容易调试。