Wygląda na to, że lockdown nie wpłynął zbytnio na Microsoft. W tym roku pojawiło się sporo nowego oprogramowania - długo oczekiwany Windows 11, nowe Visual Studio 22 i oczywiście .NET 6.0. W tych, nie najbardziej radosnych czasach, takie wiadomości są naprawdę przyjmowane z radością.
Porozmawiajmy o być może najbardziej interesującej nowości dla programistów - .NET 6.0. Nie minęło wiele czasu od momentu, gdy programiści przenieśli swoje projekty na NET 5.0, a już pojawiła się nowa wersja. Wyprzedzając pytania, zwracam uwagę na oczywistą prawdę, że wersja 6 nie jest czymś zasadniczo nowym - jest to " dopracowana" wersja 5. Większość zmian to ulepszenia lub przeprojektowania ubiegłorocznej wersji, ale szósta wersja otrzymała status LTS (Long Time Support) - wersja z długoterminowym supportem. Od tej pory będzie to dotyczyło wszystkich wersji parzystych.
Jak pamiętacie, począwszy od .NET 5.0 Microsoft postanowił połączyć wszystkie swoje frameworki w jeden, aby wyeliminować cały "bałagan". Czyli wrócili do pierwotnej koncepcji .NET Framework, tylko teraz nie jest to monolit, tylko tak wygląda.
Zmian i dodatków do NET 6.0 jest bardzo dużo i żeby ten artykuł nie zamienił się w nudną rozprawkę, chciałbym pokrótce omówić te główne, najciekawsze:
1. Crossgen2 - kompilacja wstępna
Zaktualizowane narzędzie Crossgen otrzymało drugą wersję. Stara technologia prekompilatora była, szczerze mówiąc, wadliwa i pozwalała na generowanie natywnego kodu tylko dla platformy, na której działało stare narzędzie crossgen. Teraz pozwala na uruchomienie kompilatora JIT niezależnie od platformy, stosując różne strategie i optymalizacje w zależności od potrzeb.
2. Profile-Guided Optimization (PGO)
Jest to optymalizacja kompilatora w celu nadania priorytetu kompilacji części programu. Chodzi o to, że daleko nie wszystkie części programu są używane w rzeczywistym działaniu lub są używane bardzo rzadko. Na przykład, niektóre gałęzie w else if. Tak więc, możesz uczynić program bardziej zoptymalizowanym, jeśli powiesz kompilatorowi o najczęściej używanych blokach w programie. Możesz teraz włączyć analizator, aby wykrywał często i rzadko używane fragmenty podczas pracy programu, a także opracować profil optymalizacji. Istnieją trzy scenariusze dla tej optymalizacji:
-
Statyczny - w którym kod jest dzielony na często używany i rzadko używany (hot-cold splitting). W tym przypadku profil optymalizacyjny jest tworzony tylko raz. Jeśli warunki pracy programu ulegną zmianie, będzie on musiał zostać skompilowany od nowa w celu ponownej optymalizacji. W tym podejściu najczęściej używane części programu są kompilowane i umieszczane obok siebie w pliku wykonywalnym. Pozwoli to na bardzo szybkie załadowanie się strony, dzięki wykorzystaniu cache. Wyjątkowo rzadko używany kod nie jest w ogóle kompilowany. W razie potrzeby zostanie on skompilowany w trybie runtime.
-
Dynamiczne podejście, w którym nie jest tworzony wstępny profil optymalizacji. Analizator monitoruje wykonanie programu podczas rzeczywistej pracy i rekompiluje fragmenty kodu, w przypadku konieczności optymalizacji.
-
Mieszane podejście mówi samo za siebie. Oczywiście, oba podejścia są tutaj stosowane. Oznacza to, że program jest wstępnie optymalizowany zgodnie z profilem optymalizacji. Następnie, podczas pracy, jest on regulowany zgodnie z dynamicznym schematem.
3. Hot reload
Ta funkcja sprawi Ci szczególną radość. Wreszcie, debugowanie aplikacji jest o wiele łatwiejsze! Teraz możesz uruchomić debugowanie raz i edytować kod "na znaleźć tutaj.żywo". Jeśli kiedykolwiek debugowałeś javascript w swoich projektach .NET Core, od razu zrozumiesz zasadę działania.
Zapewne pamiętasz coś, co nazywa się "Zmień i kontynuuj". I kiedyś mieliśmy możliwość zmiany kodu w czasie wykonywania, ale nie działało to za dobrze. Trzeba było ustawić punkty przerwania i aplikacja się zatrzymywała. Breakpoint musiał być ustawiony przed momentem, który zamierzaliśmy zmienić. I możliwości zmiany były bardzo ograniczone.
https://docs.microsoft.com/en-us/visualstudio/debugger/supported-code-changes-csharp?view=vs-2019
Teraz możemy poprawiać kod bezpośrednio w czasie wykonywania podczas debugowania. Następnie zapisać zmiany i zobaczyć je w czasie rzeczywistym. To znacznie przyspiesza debugowanie programów, szczególnie jeśli wiesz co i gdzie poprawić i chcesz zobaczyć wynik natychmiast, bez ponownego uruchamiania debugowania. I tak, to teraz działa również w VS Code. Lista dostępnych zmian nie jest obszerna i można ją tutaj.
4. .NET MAUI
W ramach globalizacji, czyli łączenia wszystkich frameworków w jeden, Microsoft dodaje wsparcie dla Xamarin do .NET 6. Teraz mamy możliwość tworzenia aplikacji dla systemów macOS, iOS i Android w VisualStudio. Nie będzie to jednak działać w standardowym SDK. Konieczne będzie zainstalowanie dodatkowego Optional SDK Workloads. Tak naprawdę proces tworzenia staje się coraz wygodniejszy. Utworzenie projektu na Androida to zadanie dla jednego zespołu:
dotnet new android
Nazwa Xamarin została porzucona i teraz mamy do czynienia z Multi-platform App UI, w skrócie MAUI.
5. Minimalne ramy API
Nie sposób nie wspomnieć o tak ciekawym narzędziu, jakim jest Minimal API. Ten framework pozwala na tworzenie i dostęp do metod webowych przy użyciu minimalnej ilości kodu. Nie musisz tworzyć wszystkich tych połączeń MVC, konfigurować nagłówki kontrolerów i metod, aby zbudować routing. Co więcej, Setup.cs również nie jest już potrzebny. Wystarczy Program.cs, w którym można od razu tworzyć metody webowe z routingiem.
app.MapGet("/", (Func<string>)(() => "Hello World!"));
Funkcja bez nazwy będzie na każde żądanie odpowiadać "Hello World!". Jest to dokładnie to, co jest potrzebne dla mikroserwisów lub prototypowania.
6. Obsługiwane systemy operacyjne
Microsoft opublikował listę wszystkich wspieranych OS-ów, a mianowicie:
- Windows - Windows Client, Windows 10 Client, Windows 11, Windows Server, Windows Server Core, Nano Server;
- MacOS;
- Linux - Alpine Linux, CentOS, Debian, Fedora, openSUSE, Red Hat Enterprise Linux, SUSE Enterprise Linux (SLES), Ubuntu;
- Mobile - Android i iOS.
7. Wsparcie dla architektury ARM64
Wsparcie dla ARM64 jest dostępne od NET 5 dla Windows. W wersji 6 został on rozszerzony o procesory ARM64 firmy Apple.
8. Wsparcie dla aplikacji desktopowych Blazor
Choć Blazor to framework dla aplikacji przeglądarkowych, Microsoft postanowił przełamać schemat i umożliwić tworzenie aplikacji desktopowych. Najwyraźniej Blazor udowodnił swoją wartość.
9. Optymalizacja MSBuild
Przeniesiono kompilator Razor do Roslyn Source Generators, co znacznie przyspieszyło kompilację. Roslyn Source Generators pojawił się jeszcze w NET 5 i narobił sporo "zamiesznia" za sprawą swojej zdolności do generowania kodu C # w locie podczas programowania.
10. LINQ
Nasz ulubiony LINQ również nie został zignorowany. W każdym wydaniu .NET starają się dodać coś nowego do języka (szczególnie w .NET 5) i to wydanie nie jest wyjątkiem. LINQ w ciągu ostatnich kilku lat poprawiło wydajność, a także zmniejszyło duplikację kodu. Oto krótka lista przydatnych "funkcji":
- Funkcja TryGetNonEnumeratedCount pozwala na określenie liczby elementów w sekwencji bez przechodzenia przez nie, co w niektórych przypadkach znacznie przyspiesza działanie programu;
- Funkcja Chunk dzieli elementy sekwencji na określoną liczbę grup;
- Funkcje MaxBy i MinBy pozwalają na znalezienie maksymalnego lub minimalnego elementu według podanego selektora klucza;
- Funkcje DistinctBy, ExceptBy, IntersectBy i UnionBy pozwalają również na wybór klucza;
- Funkcje ElementAt i ElementAtOrDefault zwracają element według indeksu, a różnica polega na zwróceniu wartości domyślnej;
- Funkcja FirstOrDefault posiada wreszcie możliwość ustawienia wartości domyślnej. Że tak powiem, "wasze błagania zostały wysłuchane", bo nie wszyscy byli zadowoleni z nulla;
- Funkcja Max nauczyła się akceptować komparator do porównywania wartości;
- Funkcja Take umożliwia teraz ustawienie zakresu.
11. JSON
No i oczywiście biblioteka System.Text.JSON. Główne zmiany dotyczyły serializera. Mianowicie:
- Ignorowanie cyklicznych odniesień;
- Dodano obiekt IAsyncEnumerable<T>, który zamienia się w tablicę;
- Deserializuje dokument tablicy, w którym pojawiła się metoda DeserializeAsyncEnumerable.
- Wsparcie dla generatorów źródeł - technologia bezrefleksyjnej serializacji, dzięki której program jest znacznie szybszy i tańszy;
- Dodano nowe interfejsy IJsonOnDeserialized, IJsonOnDeserializing, IJsonOnSerialized, IJsonOnSerializing, które zawierają obsługę zdarzeń o tej samej nazwie. To znaczy, że jakiś kod może być wykonywany podczas serializacji/deserializacji;
- Atrybut JsonPropertyOrder może być użyty do ustawienia kolejności, w jakiej pola są serializowane;
- Deserializacja ze strumienia;
12. HTTP/3
Protokół komunikacyjny HTTP istnieje prawdopodobnie od zawsze. Wszyscy dobrze wiedzą, że jest on oparty na innym protokole, TCP, który istnieje jeszcze dłużej. Tak, gwałtowny rozwój Internetu postawił http w trudnej sytuacji - na tle rosnącej przepustowości sieci wygląda on jak słabe ogniwo. Wreszcie pojawiła się trzecia wersja tego wspaniałego protokołu, która nie wyeliminowała problemów, ale znacznie je ograniczyła.
Nowy protokół QUIC, który zastąpił TCP, jest szybszy w przypadku utraty pakietów. Jest on szybszy podczas nawiązywania połączenia. Pozwala to na równoległe przesyłanie danych. I jest z natury bezpieczny dzięki szyfrowaniu żądań.
13. Priorytet kolejki
Pojawiła się nowa klasa PriorityQueue<TElement,TPriority>. Pozwala on na ustawienie priorytetu dla każdego dodawanego elementu oraz tworzy kolejkę priorytetową. Elementy te są pobierane począwszy od niższego priorytetu.
14. Data/godzina
Data również została dopracowana. Z najciekawszych zmian:
- Istnieją dwie nowe metody System.DateOnly i System.TimeOnly, które pozwalają na bezpośrednią pracę z datą lub czasem, a nie jak poprzednio z DateTime.
- Konwersja strefy czasowej. To znaczy, możesz teraz użyć identyfikatora Windows lub IANA podczas definiowania strefy używając metody TimeZoneInfo.FindSystemTimeZoneById. Jeżeli podczas wyszukiwania nie zostanie znaleziony identyfikator strefy jednego typu, czas jest automatycznie konwertowany na inny format odpowiadający drugiemu typowi identyfikatora.
15. Obsługa C# 10
Nowe funkcje wersji 10 wymagają osobnego artykułu. Nie będę więc nawet wymieniał tutaj tych najciekawszych. Na razie możecie zapoznać się z listą zmians.
Podsumujmy trochę - co .NET 6 ma nam do zaoferowania:
- Wydajność - rzeczywiście, dzięki różnym optymalizacjom, platforma .NET 6 jest bardzo szybka, szczególnie jeśli chodzi o web part.
- Wszechstronność - jedna platforma do tworzenia dowolnych aplikacji na różne platformy. Wielu z nich pozytywnie przyjęło ten pomysł. Próg wejścia w rozwój jest znacznie obniżony i jest to po prostu wygodne. Ale sceptyków nie brakuje. Wszyscy wiemy, że to, co uniwersalne, jest zazwyczaj gorsze od tego, co specjalne.
Oczywiście przetestowaliśmy nasze produkty pod kątem kompatybilności z nowym frameworkiem. FastReport działa tak samo dobrze na .NET 6 jak i na wersji 5.
Naszym zdaniem konsolidacja platform, języków i technologii jest właściwym kierunkiem. Owszem, wiedza techniczna młodego pokolenia maleje, ale nie jest już potrzebna. Tak jak automatyczna skrzynia biegów zastępuje manualną. Ludzie po prostu muszą jeździć, a nie myśleć o biegach i obrotach silnika. Wielu współczesnych programistów nie chce też rozumieć technicznych aspektów wdrażania tych czy innych procesów. Teraz mogą jedynie zaangażować się w proces twórczego rozwoju.