Sprawdzanie null W pętli foreach

Czy jest lepszy sposób na wykonanie:
Muszę sprawdzić, czy null się nie zdarzy.Nagłówki przed przystąpieniem do pętli

if (file.Headers != null)
{
  foreach (var h in file.Headers)
  {
   //set lots of properties & some other stuff
  }
}

Krótko mówiąc, zapis foreach wewnątrz if wygląda trochę brzydko ze względu na poziom wcięcia w moim kodzie.

Jest czymś, co oceniałoby

foreach(var h in (file.Headers != null))
{
  //do stuff
}
Możliwe?
Author: Eminem, 2012-07-31

7 answers

Jako niewielki kosmetyczny dodatek do sugestii Rune ' a, możesz stworzyć własną metodę rozszerzenia:

public static IEnumerable<T> OrEmptyIfNull<T>(this IEnumerable<T> source)
{
    return source ?? Enumerable.Empty<T>();
}

Wtedy możesz napisać:

foreach (var header in file.Headers.OrEmptyIfNull())
{
}

Zmień nazwę zgodnie z gustem:)

 86
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-31 06:40:41

Zakładając, że typ elementów w pliku.Headers is T you could do this

foreach(var header in file.Headers ?? Enumerable.Empty<T>()){
  //do stuff
}

Spowoduje utworzenie pustego pliku wyliczeniowego t if.Nagłówki są równe null. Jeśli Typ pliku jest typem, który posiadasz, rozważyłbym jednak zmianę gettera Headers. null jest wartością unknown, więc jeśli to możliwe zamiast używać null jako "I know there ' s no elements", gdy null faktycznie(/oryginalnie) powinno być interpretowane jako "I don' t know if there 's any elements" Użyj pustego zestawu, aby pokazać, że wiedz, że w zestawie nie ma żadnych elementów. Byłoby to również DRY ' er, ponieważ nie będziesz musiał sprawdzać wartości null tak często.

Edytuj jako kontynuację sugestii Jonsa, możesz również utworzyć metodę rozszerzenia zmieniającą powyższy kod na

foreach(var header in file.Headers.OrEmptyIfNull()){
  //do stuff
}

W przypadku, gdy nie możesz zmienić gettera, byłoby to moje własne preferowane, ponieważ wyraża zamiar wyraźniej, nadając operacji nazwę (OrEmptyIfNull)

 53
Author: Rune FS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-12 10:13:02

Szczerze, radzę: po prostu podlizać się testowi null. A null test to po prostu a brfalse lub brfalse.s; Wszystko inne będzie wymagało znacznie więcej pracy (testy, zadania, dodatkowe wywołania metod, niepotrzebne GetEnumerator(), MoveNext(), Dispose() na iteratorze, itp.).

Test jest prosty, oczywisty i skuteczny.

 11
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-31 06:46:54

"jeśli" przed iteracją jest w porządku, niewiele z tych" ładnych " semantyki może sprawić, że Twój kod będzie mniej czytelny.

W każdym razie, jeśli wcięcie zakłóca twoje, możesz zmienić if, aby sprawdzić:

if(file.Headers == null)  
   return;

I dostaniesz się do pętli foreach tylko wtedy, gdy we właściwości headers jest prawdziwa wartość.

Inną opcją, o której mogę myśleć, jest użycie operatora null-coalescing wewnątrz pętli foreach i całkowite uniknięcie sprawdzania null. próbka:

List<int> collection = new List<int>();
collection = null;
foreach (var i in collection ?? Enumerable.Empty<int>())
{
    //your code here
}

(zastąp zbiór z twoim prawdziwym obiektem / typem)

 9
Author: Tamir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-31 06:39:35

Używam ładnej metody rozszerzenia dla tych scenariuszy:

  public static class Extensions
  {
    public static IList<T> EnsureNotNull<T>(this IList<T> list)
    {
      return list ?? new List<T>();
    }
  }

Biorąc pod uwagę, że nagłówki są typu list, możesz wykonać następujące czynności:

foreach(var h in (file.Headers.EnsureNotNull()))
{
  //do stuff
}
 3
Author: Wolfgang Ziegler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-31 09:39:27

Używając null-operatora warunkowego i foreach (), który działa szybciej niż standardowa pętla foreach.
Musisz jednak oddać kolekcję do listy.

   listOfItems?.ForEach(item => // ... );
 1
Author: Andrei Karcheuski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-27 16:24:45

W niektórych przypadkach wolałbym nieco inny, ogólny wariant, zakładając, że z reguły domyślne konstruktory kolekcji zwracają puste instancje.

Lepiej byłoby nazwać tę metodę NewIfDefault. Może być użyteczny nie tylko dla zbiorów, więc ograniczenie typu {[2] } może być zbędne.

public static TCollection EmptyIfDefault<TCollection, T>(this TCollection collection)
        where TCollection: class, IEnumerable<T>, new()
    {
        return collection ?? new TCollection();
    }
 0
Author: N. Kudryavtsev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-25 12:08:37