Is er een "mooiere" manier om dit te doen?

Stel dat ik de rij heb

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

Maar nu wil ik vermijden om aan mijn lijst toe te voegen als de methode null retourneert. Is er een mooiere manier dan

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

?

0
Welk type is item.Items ? Is het iets dat een AddRange -methode heeft?
toegevoegd de auteur Joe White, de bron
Je kunt zoiets als dit doen; dirs.ToList (). ForEach (d => {var tmp = MyMethod (d); if (tmp! = null) item.Add (tmp);}); Ik zou echter blijven met een normale foreach-lus - u itereert de verzameling hier twee keer ( .ToList() en vervolgens de .ForEach() )
toegevoegd de auteur Rob, de bron

4 antwoord

Ik zie niet wat er mis is met een simpele lus. Eerlijk gezegd weet ik niet waarom sommige mensen een obsessieve behoefte hebben om LINQ te gebruiken of welke glimmende nieuwe tool/syntactische constructie ze recent hebben ontdekt wanneer het eenvoudigste en meest logische antwoord voor hen ligt.

Er is niets mis met je loop; zorgen maken over het oplossen van echte problemen.

10
toegevoegd
Ik verwijs graag naar LINQ als jQuery van .NET. Dat is alles.
toegevoegd de auteur BoltClock, de bron
Om recht te doen aan het OP, noemt hij (?) Nooit linq, het is mogelijk dat hij op een non-linq manier (zoals AddRange) zit
toegevoegd de auteur RichK, de bron
@RichK: bereik toevoegen zou beter zijn, maar zijn voorbeeld staat dit niet toe. Hij roept een methode MyMethod aan die een enkel object retourneert en vervolgens dat object toevoegt aan een verzameling.
toegevoegd de auteur Ed S., de bron
Het is goed om te weten wat de alternatieven zijn, dus u kunt kiezen wat u het beste vindt.
toegevoegd de auteur svick, de bron
Daar ben ik het mee eens. Dit is een enigszins verontrustende trend naar LINQ-ify elke lus in C# deze dagen:/Ik ben er schuldig aan.
toegevoegd de auteur Alastair Pitts, de bron

U kunt Selecteren() gebruiken om MyMethod() aan te roepen en de lijst vervolgens filteren met Waar() :

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

Als item.Items AddRange() ondersteunt (of als u het als een uitbreidingsmethode hiervoor schrijft), kunt u als volgt iets doen:

item.Items.AddRange(filteredDirs);

Als dit niet wordt ondersteund (en u geen uitbreidingsmethode wilt schrijven), is foreach waarschijnlijk het beste:

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

Maar er is niets mis met eenvoudige imperatieve code zoals je hebt gepost, zoals anderen al zeiden.

3
toegevoegd

Als het mijn -code was, is dit waarschijnlijk hoe het eruit zou zien:

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, als AddRange wordt ondersteund:

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

However, I find nothing terrible about the foreach case posted and, in fact: foreach { if ... } is very desirable in cases.

Dit komt omdat het trivially kan worden uitgebreid naar voor elke {if ... else ...} . C# 3.0/4.0 heeft geen bijzonder vriendelijke manier om met gepartitioneerde lijsten om te gaan en, in gevallen waar de bestelling wordt geïmporteerd, is de aanpak van partitionering en dan het afzonderlijk verwerken van de lijsten geen haalbare oplossing. In dergelijke gevallen gebruik ik nog steeds over het algemeen (maar niet altijd) LINQ voor zoveel mogelijk transformatie:

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

I do not use ForEach for side-effects and I avoid side effects in LINQ queries. This includes exceptions! Much of my code that deals with LINQ actually returns IList and not IEnumerable to ensure it is "forced" in the appropriate context. Laziness if good, except when it isn't: C# is not Haskell.

Happy codering.

2
toegevoegd
dirs.Select(dir => MyMethod(dir))
    .Where(result => result != null)
    .ForEach(result => item.Items.Add(result));

zou ik zijn hoe ik het zou aanpakken.

1
toegevoegd