Почему ReSharper предлагает преобразовать цикл for в выражение LINQ? - PullRequest
24 голосов
/ 14 февраля 2012

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

Ответы [ 7 ]

36 голосов
/ 14 февраля 2012

Скорость очень часто не имеет значения в больших частях вашего кода - вы должны написать код самым простым способом, а затем измерить его, чтобы убедиться, что он достаточно быстр .

Если ваш цикл for действительно просто запрашивает, то LINQ - это абсолютно отличный способ получить более читаемый код.Это не универсально применимо, но это то, что вы должны, по крайней мере, часто иметь в виду .

Довольно часто цикл for можно преобразовать в запрос для ленивой оценки, а затем цикл foreach.который выполняет некоторые действия с каждым значением, возвращаемым запросом.Это может помочь разделить два аспекта, позволяя вам сосредоточиться на одном за раз при чтении кода.Тем не менее, важно сохранять запросы LINQ как запросы, а не использовать внутри них побочные эффекты - он разработан с функциональным подходом, который на самом деле плохо сочетается с побочными эффектами.

Если у вас есть конкретные примеры, мы могли бы дать больше мнений о том, какие циклы имеет смысл конвертировать для использования LINQ, а какие нет.

15 голосов
/ 14 февраля 2012

Нет увеличения производительности как такового, но есть некоторые преимущества

  • Делает код более читабельным.
  • Уменьшает количество строк.
  • Прост в обслуживании.
  • В некоторых случаях вам не требуются временные переменные, которые могут потребоваться в цикле for.Используя Linq, вы можете объединять запросы.

Для получения более подробной информации вы можете обратиться:

Надеюсь, это поможет вам.

4 голосов
/ 14 февраля 2012

Вполне вероятно, что нет разницы в скорости, однако использование Linq часто может привести к более резкому коду. Это не значит, что вы всегда должны принимать предложение R # преобразовать в выражение Linq. Иногда сложные, но понятные циклы foreach преобразуются в допустимые, но не легко понимаемые выражения Linq.

3 голосов
/ 09 января 2014

Я бы сказал, что есть причина, почему бы не конвертировать иногда. Возможно, менее примечательным является то, что ReSharper не предлагает рефакторинг для преобразования выражения LINQ (обратно) в цикл for. Я несколько раз преобразовывал цикл в выражение, а затем хотел добавить некоторые дополнительные действия (часто отладочные действия) в цикл; Я должен преобразовать их обратно вручную.

Я бы предостерег от преобразования цикла for без уважительной причины. Довольно часто это действительно не улучшает читаемость, и нет других веских причин для этого (как правильно отметили другие, большинство циклов не критичны по скорости).

Я думаю, что некоторые циклы for более читабельны, чем эквивалент LINQ, потому что они визуально разбивают действия цикла на куски размера укуса. Я бы сказал, что это, как правило, небольшие циклы (три или четыре строки), которые наиболее улучшены, если превратить их в выражение в одну строку.

[Извините, этот пост в основном является мнением, но читабельность - немного субъективная тема. Троллинга нет!]

3 голосов
/ 14 февраля 2012

В общем, предложения ReSharper - это просто предложения и никаких предупреждений.Так что только вам решать, по какому пути вы пойдете: LINQ или foreach.
У меня та же проблема с предложением "Использовать 'var'".Я нажимаю на это предложение, только если думаю, что читатель мог бы лучше прочитать утверждение.
Читаемость - один из моих высших приоритетов при написании кода.

2 голосов
/ 14 февраля 2012

Привет, Linq фактически вызывает цикл for внутри. Я предполагаю, что это сводится к тому, что выражения Linq в целом легче читать / поддерживать. Если вы действительно беспокоитесь о производительности, вы можете сравнить их между собой: http://geekswithblogs.net/BlackRabbitCoder/archive/2010/04/23/c-linq-vs-foreach---round-1.aspx

0 голосов
/ 17 июля 2017

В качестве ссылки для других приведем пример цикла for и цикла for, предложенного 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;
        }

Чтобы объяснить этот код, этот цикл for получит все дубликаты в массиве.После получения всех дубликатов убедитесь, что количество элементов больше единицы, а затем верните false.

Это рекомендуемый цикл for в 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);

Может и не быть прироста производительности, но, как видно из примера, запрос LINQ чище, его легко читать,меньшие строки (которые в данном случае только одна строка кода, я просто скорректировал ее после вставки здесь) и также легко отлаживать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...