Przejdź do treści

Okiełznaj Default – Nie Daj Się Zaskoczyć

    Aby zrozumieć w pełni czego się spodziewać po FirstOrDefault (lub SingleOrDefault) musisz zrozumieć, czym wyrażenie wartości domyślnych (default) jest.

    Default w typach wartościowych

    Typy wartościowe w C#: int, long, double, float, byte, char, bool, enumstruktury.

    Poniżej kilka przykładów wywołania wyrażenia default. Dla zmiennej typu bool oraz enum jest to również 0, przy czym w przypadku:

    • bool, 0 odpowiada wartości False
    • enum, 0 odpowiada pierwszej wartości tego enuma (domyślny default) lub tej z przypisaną wartością 0
    • char, 0, a dokładniej '\0' (U+0000), „null character”

    Default w typach referencyjnych

    Typy referencyjne w C#: klasydelegaty, interfejsytablice, zmienne string, czyli elementy rozszerzające klasę System.Object oraz System.String

    Poniżej kila przykładów wraz z rezultatami otrzymanymi w konsoli.

    Default i typ nullable

    Zawsze zwracana jest wartość null. Dla pełnej pewności sprawdzenie poniżej przez is null. Więcej o typach nullable i jak możesz do nich podejść, przeczytasz w tym artykule.

    FirstOrDefault() vs SingleOrDefault()

    Różnica między First a Single

    Obydwie metody (First() oraz Single()) zwracają pojedynczy element z kolekcji. Z tą różnicą, że Single daje zapewnienie istnienia jednego elementu spełniającego warunek, a First zwraca pierwszy element spełniający warunek. W przypadku braku uporządkowania elementów (OrderBy()) zwracane elementy w kolejnych wywołaniach tego samego kodu mogą okazać się losowe.

    Or Default – Nie Daj Się Zaskoczyć

    Wybierze Pierwszy/Pojedynczy element lub element domyślny.

    Przyjrzymy się poniżej pięciu przypadkom i temu co w rezultacie możesz otrzymać.

    1. Istnieje element spełniający warunek m.Number == 1 – rezultat nie ma wartości null
    2. Nie istnieje element spełniający warunek m.Number == 1 = rezultat ma wartość null
    3. Nie istnieje element spełniający warunek m.Number == 1, a dodatkowo wybieramy (Select) konkretne pole typu wartościowego.
      • Rezultat może okazać się niejednoznaczny, wątpliwości rozwiewam w punkcie 5 poniżej.
    4. Nie istnieje element spełniający warunek m.Number == 1, a dodatkowo wybieramy (Select) konkretne pole typu nullable
    Odbierz darmowy eBook

    5. Powyższy przykład nr 3, wprowadza niepewność, czy dany element nie został znaleziony w kolekcji, czy został i przyjmuje akurat wartość 0 (domyślną dla long). Zakładając że cały obiekt nie jest potrzebny, możesz dokonać boxingu (new {m.Number}) tego jednego elementu i mieć pewność z jakim przypadkiem masz do czynienia.
    Szczególnie przydatne przy optymalizacji operacji na IQueryable, gdy chcemy pobierać z bazy tylko te dane które są potrzebne.

    Ciekawostka

    Operator default możesz wykorzystać jak na poniższym przykładzie, aby utworzyć wartość domyślną typu:

    int a = default(int);

    Od wersji języka C# 7.1, można użyć samego słowa kluczowego default aby zainicjować zmienną z domyślną wartością:

    int a = default;

    Default a Swich

    Warto dodać, że default jest też wykorzystywany w instrukcji wyboru switch. Przy czym w tej instrukcji definiuje domyślne działanie, a nie reprezentuje wartości, jak np. default(int).

    Podsumowanie

    Znajomość wartości domyślnych i ich zachowań z pewnością przyda się w programowaniu. Nie daj się zaskoczyć metodom FirstOrDefault/SingleOrDefault i zredukuj czas poświęcony debugowaniu i szukania przyczyn buga / problemu / niechcianego zachowania kodu.

    Po więcej ciekawych treści zapraszam do do listy mailowej oraz do strony Programista Jutra na FB.

    Subskrybuj
    Powiadom o
    guest
    0 Komentarze
    Najstarsze
    Najnowsze Najwięcej głosów