Есть ли "более красивый" способ сделать это? - PullRequest
0 голосов
/ 07 декабря 2011

Скажи, у меня есть линия

dirs.ToList().ForEach(d => item.Items.Add(MyMethod(d)));

Но теперь я хочу избежать добавления в мой список, если метод возвращает ноль. Есть ли более красивый способ, чем

foreach(var d in dirs)
{
    object obj = MyMethod(d);
    if(obj != null)
        myList.Items.Add(obj);
}

Ответы [ 4 ]

10 голосов
/ 07 декабря 2011

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

Тамнет ничего плохого в вашей петле;беспокоиться о решении реальных проблем.

3 голосов
/ 07 декабря 2011

Вы можете использовать Select() для вызова MyMethod(), а затем отфильтровать список с помощью Where():

var filteredDirs = dirs.Select(MyMethod)
                       .Where(d => d != null);

Если item.Items поддерживает AddRange() (или если вы пишете это как метод расширения для него), вы можете сделать что-то вроде этого:

item.Items.AddRange(filteredDirs);

Если он не поддерживает его (и вы не хотите писать для него метод расширения), foreach, вероятно, лучше:

foreach (var dir in filteredDirs)
    item.Items.Add(dir);

Но нет ничего плохого в простом императивном коде, который вы опубликовали, как говорили другие.

2 голосов
/ 07 декабря 2011

Если бы это был мой код, скорее всего, это выглядело бы так:

foreach(var name in dirs         // dunno if "name" is correct :)
      .Select(d => MyMethod(d))  // or .Select(MyMethod), depending
      .Where(n => n != null)) {
    myList.Items.Add(name);
}

Of, если AddRange поддерживается:

myList.Items.AddRange(
  dirs.Select(d => MyMethod(d))
      .Where(n => n != null));

Однако , я не нахожу ничего страшного в опубликованном случае foreach, и фактически: foreach { if ... } является очень желательным в случаях.

Это потому, что он может быть тривиально расширен до foreach { if ... else ... }. В C # 3.0 / 4.0 нет очень дружественного способа работы с секционированными списками, и в случаях, когда заказ импортируется, подход секционирования и , а затем обработка списков по отдельности не является жизнеспособным решением. В таких случаях я все еще обычно (но не всегда) использую LINQ для максимально возможного преобразования:

foreach(var name in dirs
      .Select(d => MyMethod(d))) {
   if (name != null) {
     myList.Items.Add(name);
   } else {
     SingMerrySongsAndDanceAHappyLittleJig(); // or ... whatever
   }
}

I не использовать ForEach для побочных эффектов, а I избегать побочных эффектов в запросах LINQ. Это включает исключения! Большая часть моего кода, имеющего дело с LINQ, на самом деле возвращает IList<T>, а не IEnumerable<T>, чтобы убедиться, что он «принудительно» в соответствующем контексте. Лень, если хорошо, за исключением случаев, когда это не так: C # не Haskell.

Удачного кодирования.

1 голос
/ 07 декабря 2011
dirs.Select(dir => MyMethod(dir))
    .Where(result => result != null)
    .ForEach(result => item.Items.Add(result));

было бы так, как я бы поступил.

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