Разумно ли использовать LINQ для замены циклов?

теперь, когда у нас есть огромная функциональность благодаря LINQ, мне интересно, какой синтаксис предпочтительнее. Например, я нашел следующий метод (просто подумал, что это хороший пример):

foreach (FixtureImageServicesData image in _fixture.Images)
{
    if (image.Filename != _selectedFixtureImage.Filename && image.IsPrimary)
    {
        image.IsPrimary = false;
        image.IsChanged = true;
    }
}

если бы мы должны были преобразовать его в подход LINQ, это выглядело бы так (не проверено):

_fixture.Images.Where(x => x.Filename != _selectedFixtureImage.Filename && x.IsPrimary).ForEach(x => { x.IsPrimary = false; x.IsChanged = true; });

что бы вы хотели видеть и поддерживать? Это безумие или гениальность?

3 ответов


С помощью ForEach метод расширения в порядке, но есть промежуточный подход:

// Rename 'query' to something meaningful :)
var query = _fixture.Images
                    .Where(image => _selectedFixtureImage.Filename 
                                    && image.IsPrimary);

foreach (FixtureImageServicesData image in query)
{
    image.IsPrimary = false;
    image.IsChanged = true;
}

если вы do использовать ForEach метод, я бы определенно отформатировал его в нескольких строках:

_fixture.Images
    .Where(image => _selectedFixtureImage.Filename && image.IsPrimary)
    .ForEach(image => { image.IsPrimary = false; image.IsChanged = true;});

(уменьшенный отступ, чтобы избежать обертывания...)

или:

_fixture.Images
        .Where(image => _selectedFixtureImage.Filename && image.IsPrimary)
        .ForEach(image => { image.IsPrimary = false; 
                            image.IsChanged = true; });

возможно, вы даже захотите извлечь" создание несырьевого " бита в отдельный метод, и в этот момент у вас будет:

_fixture.Images
        .Where(image => _selectedFixtureImage.Filename && image.IsPrimary)
        .ForEach(MakeNonPrimary);

Это напоминает мне немного "Должен ли я использовать Regex или стандартные строковые функции" или "должен ли я использовать XSLT/XPATH для преобразования XML или использовать SelectSingleNode()".

первый вариант (т. е. Regex/ XSLT / Linq) часто считается более элегантным и мощным тем, кто потратил некоторое время на его изучение.

в то время как для всех остальных он кажется менее читаемым и более сложным по сравнению со вторым вариантом (т. е. строковые функции, SelectSingleNode (), простой foreach петля.)

в прошлом меня обвиняли в чрезмерном усложнении вещей, используя Regex и XSLT/XPATH в моем дизайне.

совсем недавно меня обвинили в том, что я" боюсь изменений", предпочитая простые foreach (и даже for) петли во многих ситуациях над Linq Where, Foreach и т. д.

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

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


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