简体   繁体   中英

Why does ReSharper suggest I convert a for loop into a LINQ expression?

In Visual Studio Re-Sharper keeps recommending I convert a for loop to a linq expression but what is the reason for this?

Which is faster?

Here are some example loops where resharper suggests a linq conversion:

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;
    }
}

And this simpler example:

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 + ">";
    }
}

Speed is very often irrelevant in large portions of your code - you should write code the simplest way, and then measure it to make sure it's fast enough .

If your for loop is really just querying, then LINQ is absolutely a great way to end up with more readable code. It's not universally applicable, but it's something you should at least bear in mind frequently.

Quite often a for loop can be converted into a query to be evaluated lazily, and then a foreach loop which performs some action on each value returned by the query. That can help separate the two aspects, letting you focus on one at a time when reading the code. It's important to keep LINQ queries as queries though, rather than using side-effects within them - it's designed to have a functional approach, which really doesn't mix pleasantly with side-effects.

If you have some concrete examples, we could give more opinions about which loops would make sense to convert to use LINQ, and which wouldn't.

No performance gain as such, but some benefits

  • Makes code more readable.
  • Reduces the number of lines.
  • Easy to maintain.
  • In some cases you don't require temporary variables, which you might require in for loop. Using Linq you can chain queries.

For more details you can refer:

Hope this helps you.

It's probable that there's no difference in speed, however using Linq can often result in terser code. That's not to say you should always accept R#'s suggestion to convert to a Linq expression. Sometimes complex but understandable foreach loops are converted into valid but not easily understood Linq expressions.

I'd say there is a reason why not to convert sometimes. It is perhaps less admirable that ReSharper does not offer a refactoring to convert a LINQ expression (back) into a for-loop. I have on a few occasions converted a loop into an expression and then later wanted to put in some further actions (often debugging actions) within the loop; I have to convert them back by hand.

I would warn against converting a for-loop without good reason. Quite often it really doesn't improve readability, and there isn't any other strong reason to do it (as others have rightly pointed out, most loops are not speed critical).

I think some for-loops are more readable than the LINQ equivalent, because they visually break down the actions of the loop into bite-size pieces. I'd say that it tends to be small loops (three or four lines) that are most improved by making them into an expression on one line.

[Sorry this post is mostly opinion, but readability is a bit of a subjective subject. No trolling!]

In general ReSharper's suggestions are just suggestions and no warnings. So it's only up to you to decide what way you go: LINQ or foreach.
I have the same issue with suggestion "Use 'var'". I click that suggestion only if I think the reader could better read the statement.
Readability is one of my highest priorities while writing code.

Hi Linq is actually calling a for loop internally. I guess it comes downs to that Linq expressions are in general easier to read/ maintain. If you are really concerned about performance there is a good comparison between the two: http://geekswithblogs.net/BlackRabbitCoder/archive/2010/04/23/c-linq-vs-foreach---round-1.aspx

As reference for others, here is an example of for loop and a for loop suggested by Resharper

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;
        }

To explain this code, this for loop will get all the duplicates on an array. After getting all the duplicates, check if count of items are greater than one, then return false.

This is the suggested for loop in LINQ:

  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);

There might be no performance gains, but as you can see from the example, a LINQ query is cleaner, easy to read, lesser lines (which in this case, only one line of code, I just adjusted it after pasting it here) and easy to debug as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM