Похоже, что локдаун не сильно отразился на компании Microsoft. В этом году открылся рог изобилия и на нас посыпались новинки софтверного рынка - это и долгожданная Windows 11, и новая Visual Studio 22, и, конечно же .NET 6.0. В эти, не самые веселые времена, такие новости действительно радуют.
Давайте поговорим о, пожалуй, самой интересной для разработчиков новинке - .NET 6.0. Не успели разработчики перевести свои проекты на NET 5.0, как уже подоспела новая версия. Забегая вперёд отмечу очевидную правду, что версия 6 не является чем-то принципиально новым - это “допиленный” вариант 5-й. Большая часть изменений - это доработанные или переработанные решения из прошлогоднего релиза, но шестая версия получила статус LTS (Long Time Support) - стала версией с долговременной поддержкой. Отныне это будет касаться всех четных версий.
Как вы помните, начиная с .NET 5.0 компания Microsoft решила объединить все свои фреймворки в один, дабы устранить весь этот "зоопарк". То есть пришли к изначальной концепции .NET Framework, только теперь это не монолит, а только выглядит так.
Изменений и добавлений в NET 6.0 достаточно много, и чтобы статья не превратилась в утомительный трактат, предлагаю кратко рассмотреть основные, наиболее интересные:
1. Crossgen2 - Предварительная компиляция
Обновленная утилита Crossgen получила вторую версию. Старая технология предварительной компиляции была, прямо скажем, несовершенной и позволяла только генерировать нативный код только для той платформы, на которой была запущена старая утилита crossgen. Сейчас она позволяет запускать JIT компилятор независимо от платформы применяя разные стратегии и оптимизации в зависимости от ситуации.
2. Profile-Guided Optimization (PGO)
Это оптимизация компилятора для выставления приоритетов компиляции частей программы. Все дело в том, что далеко не все части программы используются в реальной эксплуатации или используются крайне редко. Например, какие-нибудь экзотические ветвления в else if. Так вот программу можно сделать более оптимизированной, если указать компилятору на часто используемые блоки программы. Теперь есть возможность включить анализатор, который при эксплуатации программы определит часто и редко используемые участки, а также составит профиль оптимизации. Предусмотрено три сценария этой оптимизации:
- Статический - в котором код разделяется на часто и редко используемый (hot-cold splitting). В этом случае профиль оптимизации составляется лишь единожды. При изменении условий эксплуатации программы придется составлять его заново для переоптимизации. При этом подходе наиболее часто используемые части программы компилируются и помещаются в исполняемом файле рядом. Это позволит загружать его очень быстро, благодаря использованию кэша. Крайне редко используемый код вообще не компилируется. При необходимости он будет скомпилирован уже в процессе выполнения программы.
- Динамический подход, где предварительный профиль оптимизации не составляется. Анализатор следит за исполнением программы во время реальной эксплуатации и перекомпилирует участки кода в случае необходимости оптимизации.
- Смешанный подход говорит сам за себя. Тут конечно же используются оба подхода. То есть программа оптимизируется изначально по профилю оптимизации. Затем, в ходе эксплуатации она корректируется по динамической схеме.
3. Hot reload
Эта фича особенно вас порадует. Наконец отладка приложений сильно упрощается! Теперь вы можете запустить отладку один раз и править код "на живую". Если вы когда-нибудь отлаживали javascript в своих .NET Core проектах, то вы поймете принцип сразу.
Наверняка вы помните такую штуку, как "Изменить и продолжить". И раньше у нас была возможность изменить код во время выполнения, но работало это не очень удобно. Приходилось ставить брейкпоинты и приложение вставало на паузу. Брейкпоинт обязательно должен быть установлен до момента, который предполагается исправлять. Да и возможности по изменению были весьма ограничены.
https://docs.microsoft.com/en-us/visualstudio/debugger/supported-code-changes-csharp?view=vs-2019
Теперь мы можем исправить код прямо при выполнении программы во время отладки. Затем сохранить изменения и увидеть их в реальном времени. Это значительно ускоряет отладку программ, особенно если вы знаете что и где нужно исправлять и хотите сразу увидеть результат без перезапуска отладки. И да, теперь это работает и в VS Code. Список доступных изменений не велик и доступен по ссылке.
4. .NET MAUI
В рамках глобализации, то есть объединения всех фреймворков в один, Microsoft добавляет в .NET 6 поддержку Xamarin. Теперь нам доступна разработка под macOS, iOS и Android в VisualStudio. Однако в стандартном SDK это не заработает. Потребуется установка дополнительного Optional SDK Workloads. На самом деле разработка становится все удобнее. Создать проект на Android - дело одной команды:
dotnet new android
От названия Xamarin решили отказаться и теперь нам представили Multi-platform App UI или сокращенно MAUI.
5. Minimal API Framework
Нельзя обойти стороной такой интересный инструмент как Minimal API. Этот фреймворк позволяет обходиться минимальным кодом для создания и доступа к веб-методам. Не нужно создавать всю эту MVC обвязку, настраивать заголовки контроллеров и методов, чтобы выстроить роутинг. Более того, Setup.cs тоже больше не нужен. Достаточно лишь Program.cs в котором вы сразу можете создавать веб-методы с роутингом.
app.MapGet("/", (Func<string>)(() => "Hello World!"));
Неименованная функция вернет "Hello World!" на любой запрос. Это именно то, что так нужно для микросервисов или прототипирования.
6. Поддерживаемые операционные системы
Microsoft опубликовали список всех поддерживаемых ОС, а именно:
- 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;
- Мобильные - Android и iOS.
7. Поддержка архитектуры ARM64
Поддержка ARM64 появилась еще в NET 5 для Windows. В шестой же версии она расширилась на процессоры ARM64 Apple.
8. Поддержка десктоп приложений Blazor
Несмотря на то, что Blazor это фреймворк для браузерных приложений, Microsoft решил сломать шаблон и дать возможность создавать десктоп приложения. Видимо Blazor доказал свою состоятельность.
9. Оптимизация MSBuild
Перевели Razor-компилятор на Roslyn Source Generators, что значительно ускорило сборку. Roslyn Source Generators появился еще в NET 5 и наделал много “шума” благодаря возможности генерировать код C # на лету во время разработки.
10. LINQ
Наш любимый LINQ тоже не оставили без внимания. В каждом выпуске .NET стараются добавить что-то новое в этот язык (особенно в .NET 5) и этот релиз не стал исключением. В LINQ за последние несколько лет улучшили производительность, а также уменьшили дублирование кода. Вот небольшой список полезных "фишек":
- Функция TryGetNonEnumeratedCount позволяет определить количество элементов в последовательности, не перебирая их, тем самым значительно ускоряя работу программу в некоторых случаях;
- Функция Chunk разбивает элементы последовательности на заданное количество групп;
- Функции MaxBy и MinBy позволяют найти максимальный или минимальный элемент по заданному ключевому селектору;
- Функции DistinctBy, ExceptBy, IntersectBy и UnionBy также позволяют выполнять действия по ключевому селектору;
- Функции ElementAt и ElementAtOrDefault возвращают элемент по индексу с разницей в виде возврата значения по умолчанию;
- Функция FirstOrDefault наконец-то обзавелась возможностью задавать значение по умолчанию. Так сказать, “ваши мольбы были услышаны”, ведь не всех устраивал null;
- Функция Max научилась принимать компаратор для сравнения значений;
- Функция Take теперь позволяет задавать диапазон.
11. JSON
Ну, и как же без доработок библиотеки System.Text.JSON. Основные изменения коснулись сериализатора. А именно:
- Игнорирование цикличных ссылок;
- Добавился объект IAsyncEnumerable<T>, который превращается в массив;
- Десериализация документа-массива, где появился метод DeserializeAsyncEnumerable.
- Поддержка source generators - технология сериализации без рефлексии, что значительно ускоряет и удешевляет работу программы;
- Добавили новые интерфейсы IJsonOnDeserialized, IJsonOnDeserializing, IJsonOnSerialized, IJsonOnSerializing, которые содержат одноименные обработчики событий. То есть можно выполнять какой-либо код во время сериализации/десериализации;
- С помощью атрибута JsonPropertyOrder можно задавать порядок сериазации полей;
- Десериализация из потока;
Также очень интересная "фича" - поддержка работы с JSON документом как с DOM. Эта особенность довольно полезна, поскольку часто просто не хочется плодить POCO-объекты для простых операций. Не стоит забывать, что DOM-подход к работе с JSON как бы то не было ведёт к снижению производительности и перерасходу ресурсов. Нас заверяют, что такого не произойдет, но насколько это правда - узнаем на практике.
12. HTTP/3
Протокол обмена данными HTTP существует, наверное, уже вечность. Все прекрасно знают, что он основан на другом протоколе TCP, который существует еще дольше. Да, бурное развитие интернета поставило http в затруднительное положение - на фоне роста пропускных способностей сетей он выглядит слабым звеном. И вот, наконец, до нас дошла третья версия этого замечательного протокола, которая хоть и не сняла проблемы, но существенно понизила их градус.
Новый протокол QUIC, который сменил TCP, работает быстрее в случае потери пакетов. Он быстрее при установке соединения. Он позволяет передавать данные параллельно. И он изначально безопасный благодаря шифрованию запросов.
13. Приоритет очереди
Появился новый класс - очередь с приоритетом PriorityQueue<TElement,TPriority>. Он позволяет задавать приоритет по каждому добавленному элементу и создает очередь приоритетов. Изымаются эти элементы, начиная с меньшего приоритета.
14. Дата/Время
С датой тоже поработали. Из наиболее интересных изменений:
- Появилось два новых метода System.DateOnly и System.TimeOnly, которые позволяют работать непосредственно с датой или временем, а не DateTime, как раньше.
- Конвертация часовых поясов. То есть теперь при определении пояса с помощью метода TimeZoneInfo.FindSystemTimeZoneById можно использовать идентификатор Windows или IANA. Если при поиске идентификатор пояса одного типа найден не будет, то время автоматически преобразуется в другой формат, соответствующий второму типу идентификатора.
15. Поддержка C# 10
О новых возможностях 10-й версии нужно писать отдельную статью. Поэтому даже не буду упоминать тут самое интересное. Пока что вы можете ознакомиться с этим списком изменений.
Давайте подведём небольшие итоги - что же нам предлагает .NET 6:
- Производительность - действительно, благодаря различным оптимизационным фичам платформа .NET 6 очень быстрая, особенно, если говорить о веб-части.
- Универсальность - единая платформа для создания любых приложений для различных платформ. Многие восприняли эту идею положительно. Порог вхождения в разработку сильно сокращается, да и просто удобно. Но и скептиков хватает. Все мы знаем, что универсальное, как правило, хуже специального.
Мы, конечно, же протестировали наши продукты на совместимость с новым фреймворком. FastReport работает на .NET 6 также прекрасно, как и на 5 версии.
От себя можем добавить, что на наш взгляд, вектор консолидации платформ, языков и технологий правильный. Да, технические знания у молодого поколения снижаются, но они уже и не нужны. Также как коробка автомат вытесняет механическую. Людям нужно просто ездить и не задумываться о передачах и оборотах двигателя. Также и многим современным разработчикам не хочется разбираться в технических тонкостях реализации тех или иных процессов. Теперь они могут заниматься только творческим процессом разработки.