Подтвердить что ты не робот

Почему ReSharper предлагает преобразовать цикл for в выражение LINQ?

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

Ответ 1

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

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

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

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

Ответ 2

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

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

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

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

Ответ 3

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

Ответ 4

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

Ответ 5

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

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

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

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

Ответ 6

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

Ответ 7

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

Это предложение для цикла в 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 чище, легко читается, меньшие строки (в этом случае только одна строка кода, я только что скорректировал его после вставки здесь) и легко отлаживать также.