Artykuł

freeimages.com freeimages.com
maj 04 2016
0

Najciekawsze funkcje C# 6.0, które warto znać

Czołowi blogerzy .Netowi zajmują się obecnie nowościami, które można będzie spotkać w stabilnej wersji 7.0 języka C#. W praktyce jednak, nie każdy może tak łatwo brnąć do przodu i podejrzewam, że jest sporo deweloperów, którzy wciąż nawet nie spróbowali szóstki.

Przyczyną tego stanu rzeczy najczęściej jest praca w firmie, która już jakiś czas funkcjonuje na rynku. W takiej sytuacji duży nacisk stawiamy na stabilność kodu, a każda nowa wersja czegokolwiek, stwarza potencjalne ryzyko błędu. Kompatybilny wstecz C# nie jest w tym miejscu wyjątkiem.

Dziś chciałbym Wam przedstawić kilka opcji z tej wersji języka, które rzeczywiście mogą uprzyjemnić Waszą codzienną pracę z tą technologią i które być może zachęcą Was (lub Waszych pracodawców), do ryzyka związanego z przejściem na nowszą wersję frameworka i tym samym języka C#.

Nowy sposób na inicjalizację słownika

C# 6.0 wprowadza nowy sposób inicjalizacji słowników, który wygląda trochę tak, jakbyśmy inicjalizowali tablicę asocjacyjną. Jak dla mnie nowy sposób wydaje się być bardzo przejrzysty, ponieważ jawnie widać jak w tym słowniku rzeczywiście składujemy dane. Taki syntax powinien spodobać się również fanom języków skryptowych:)

Dictionary<string, int> peopleAges = new Dictionary<string, int>
{
    ["Adam"] = 21,
    ["Ania"] = 32,
    ["Kamil"] = 16
};
Console.WriteLine(peopleAges["Adam"]);

Inicjalizacja właściwości

Czasem gdy korzystamy z właściwości w naszych klasach, fajnie byłoby, gdyby były one ustawione wartościami inne niż domyślne dla danego typu. C# 6.0 w końcu daje nam taką możliwość i nie musimy tego robić np. w konstruktorze klasy, ale od razu w deklaracji wybranej przez nas właściwości! Poniżej przykład:

public class Filter
{   
    public bool IsEnabled { get; set; } = true;
    
    public string Type { get; } = "classFilter";            
}

Jak widać, nowy mechanizm działa niezależnie od typu, a ponadto funkcjonuje on nawet w przypadku właściwości, które mają tylko geta. Innymi słowy takie przypisanie ustawia bazową wartość, której później nie jesteśmy w stanie zmienić. Oczywiście jeśli w właściwość będzie operować na złożonym obiekcie, to wciąż będziemy mogli zmieniać jego wewnętrzne właściwości :-)

Null propagation operator

Bardzo często parsując obiekty odpowiedzi z API, mamy do czynienia z wielopoziomowymi strukturami, w których bardzo łatwo napatoczyć się na nulla. Wyobraźmy sobie, że iterując w pętli, chcemy wyświetlić ulicę, na której mieszka każdy pacjent. Jednocześnie może się zdarzyć, że nie będziemy mieli takiej informacji w bazie danych, ponieważ adres nie był wymagany na formularzu rejestracji. W takiej sytuacji musimy sprawdzać, czy obiekt adresu nie jest nullem i w przypadku gdy został on zdefiniowany, wyświetlić ulicę pacjenta. Widzicie już tutaj potencjalny problem? Łatwo jest teraz wygenerować kawał brzydkiego kodu, który będzie sprawdzał poprawność danych.

Na szczęście idą zmiany, a jedną z nich jest tytułowy operator. Wyobraźmy sobie przykładowe klasy:

public class Patient
{
    public string FirstName { get; set;}
    
    public string LastName { get; set; }
    
    public Address Address { get; set; }
    
    //
}

public class Address
{
    public string Street { get; set;}
    
    // 
}

Teraz spójrzmy na testowy kod, który normalnie wygenerowałby błąd:

Patient patient = new Patient{
    FirstName = "Adam", 
    LastName = "Kowalski"
};
Console.WriteLine(patient.Address.Street);

Oczywiście przyczyna błędu jest jasna - nie zdefiniowaliśmy adresu dla tego pacjenta, a chcemy wyświetlić ulicę, która jest składową adresu. Czy idzie obejść ten problem w jakiś elegancki sposób, który nie będzie wymagał IFów? Okazuje się, że tak i teraz można napisać coś takiego:

Console.WriteLine(patient.Address?.Street ?? 
    "Wskazana osoba nie posiada zdefiniowanego adresu.");

W przykładzie wykorzystałem jeszcze dodatkowo operator ?? który pozwala nie jako określić wartość domyślną. Operator null propagation, działa na dowolnej ilości poziomów.

Await w catch i finally

Dotychczas programując asynchronicznie, mogliśmy wykorzystywać słówko kluczowe await, tylko w części try. Od teraz można z niego korzystać w pełni zarówno w sekcji try, jak również catch i finally. Poniższy przykład jest oczywiście totalnie bez sensu, ale kompiluje się i działa:-)

public async Task TestAsync()
{
    try
    {
        await Task.FromResult(0);
    }
    catch(Exception e)
    {
        await Task.FromResult(0);
    }
    finally
    {
        await Task.FromResult(0);
    }
}

Interpolacja stringów

Ostatnią z nowości jest tzw. interpolacja stringów. Dotychczas wykorzystywaliśmy metodę string.format, która niestety miała swoje wady. Przede wszystkim, parametry opisywaliśmy za pomocą liczb, dlatego też tak na dobrą sprawę, jeśli sami nie pisaliśmy określonego formatu, mogliśmy nie wiedzieć, co tak naprawdę w danym miejscu trzeba podstawić. Nowe rozwiązanie jest dużo bardziej czytelne i wygląda ono tak:

string name = "Jurek";
Console.WriteLine($"Witaj {name}");

Jak widzicie, do funkcji WriteLine podstawiliśmy format, w którym pola wypełniane są na bazie wcześniej utworzonych zmiennych. W końcu jest to czytelne i z góry wiadomo co i gdzie trzeba podstawić;)

Aby korzystać z powyższych dóbr, należy zainstalować najnowszą wersję swojego ulubione IDE - Visual Studio w wersji 2015+ lub Visual Studio Code. Warto to zrobić, ponieważ nie tylko zyskamy dostęp do nowych funkcjonalności, ale jednocześnie będziemy używać aktualnie wspieranej wersji frameworka:-)

Warto również zwrócić uwagę, że sporo z tych funkcjonalności to tak na dobrą sprawę ukłon w stronę programisty, by nie musiał on pisać brzydkiego kodu. Wskazane operatory, czy rozwiązania pod spodem(tj. w IL) działają w stary i dobrze znany sposób.

Szerzej o wszystkich zmianach pisał Piotr Zieliński na swoim blogu. W tym poście znajdziecie podsumowanie zmian wprowadzonych w wersji 6.0.

Data ostatniej modyfikacji: 07.05.2016, 22:44.

Podoba Ci się ten wpis? Powiedz o tym innym!

Send to Kindle

Komentarze

blog comments powered by Disqus