﻿# Что нового в \.NET 7?

Вышел \.NET 7, а это значит, что можно вдоволь насладиться различными нововведениями и фишками\. Расскажем про самые интересные улучшения: C\# 11, контейнеры, производительность, GC и прочее\.

![1009_Whats_New_In_NET7_ru/image1.png](https://import.viva64.com/docx/blog/1009_Whats_New_In_NET7_ru/image1.png)

## C\# 11

Мы уже выпустили [статью](https://pvs-studio.ru/ru/blog/posts/csharp/1002/), посвящённую разбору нововведений в C\# 11\. В ней мы прошлись по новым особенностям: обобщённой математике, исходным строкам, модификатору _required_, параметрам типа в атрибутах и прочему\.

Кстати, мы уже работаем над поддержкой \.NET 7 и C\# 11 — она будет добавлена в PVS\-Studio 7\.22\. Релиз запланирован на начало декабря, а загрузить свежую версию анализатора можно будет [здесь](https://pvs-studio.ru/ru/pvs-studio/try-free/)\. Если хотите попробовать бету уже сейчас, [напишите нам](https://pvs-studio.ru/ru/about-feedback/) :\)\.

## Native AOT

AOT \(ahead\-of\-time\) – компиляция приложения не в промежуточный, а сразу в машинный код\. Native AOT использует ahead of time компилятор для компиляции IL в машинный код во время публикации [self\-contained](https://learn.microsoft.com/en-us/dotnet/core/deploying/#publish-self-contained) приложения\. Native AOT был переведён из статуса экспериментального\. Основными преимуществами native AOT приложений являются:

* время запуска;
* использование памяти;
* работа на платформах с ограничениями \(JIT недоступен\)\.

Native AOT приложения имеют ряд ограничений:

* нет динамической загрузки \(например, _Assembly\.LoadFile_\);
* нет генерации кода во время выполнения \(например, _System\.Reflection\.Emit_\);
* нет C\+\+/CLI;
* и т\. д\.

## On Stack Replacement \(OSR\)

В \.NET существует такое понятие, как многоуровневая компиляция \(Tiered Compilation\)\. Если говорить простым языком, то многоуровневая компиляция снижает время запуска приложения\. Как? Изначально JIT будет генерировать плохо оптимизированный машинный код \(tier\-0\) для методов, т\. к\. это просто требует меньше времени\. Если же количество вызовов метода переступает за определённый порог, то JIT cгенерирует для этого метода более оптимизированный код \(tier\-1\)\. Данный подход не работает, например, с циклами, т\. к\. это может приводить к ухудшению производительности\. К слову, на данный момент существует всего два уровня\.

[OSR](https://devblogs.microsoft.com/dotnet/performance_improvements_in_net_7/#on-stack-replacement) позволяет заменять машинный код, который выполняется в данный момент, на новый — более оптимизированный\. Ранее такая возможность была только между вызовами метода\. Подобный подход позволяет применять многоуровневую компиляцию ко всем методам\. Благодаря этому можно добиться более быстрой компиляции и при этом стабильной производительности\. Судя по тестам Microsoft, внедрение данной технологии помогло на 25 % ускорить запуск нагруженных приложений\. OSR в \.NET 7 включена по умолчанию для x64 и Arm64\.

\{\{PROMO\_POPULAR\}\}

## Централизованное управление пакетами \(CPM\)

Управление зависимостями для многопроектных решений может оказаться сложной задачкой\. Теперь же в ситуациях, когда требуется управление общими зависимостями для нескольких проектов, вы можете использовать [централизованное управление NuGet пакетами](https://learn.microsoft.com/en-us/nuget/consume-packages/Central-Package-Management)\. Для централизованного управления зависимостями потребуется добавить файл _Directory\.Packages\.props_ в корень решения\. Благодаря CPM версия пакета указывается только в _Directory\.Packages\.props_, а в проектах требуется лишь сослаться на пакет\.

## GC Regions

Регионы GC – это функция, которая разрабатывается уже несколько лет\. Если раньше приходилось иметь несколько больших сегментов памяти \(например, 1 ГБ\), то теперь GC поддерживает множество маленьких областей \(например, 4 МБ\)\. Это позволяет GC быть более гибким в вопросах перепрофилирования областей памяти из одного поколения в другое\.

В \.NET 7 регионы используются по умолчанию для 64\-битных приложений\. Подробности по данному вопросу можно получить из [статьи](https://devblogs.microsoft.com/dotnet/put-a-dpad-on-that-gc/) архитектора \.NET GC\.

## Rate Limiting

Rate limiting – это механизм ограничения объёма доступа к ресурсу\. Таким образом можно задать определённый лимит доступа, например, к базе данных\.

Для написания ограничителя в \.NET 7 был добавлен NuGet пакет _System\.Threading\.RateLimiting_\. В основном работа будет происходить с абстрактным классом _RateLimiter_\. Один из примеров работы от Microsoft:

```cpp
RateLimiter limiter = GetLimiter();
using RateLimitLease lease = limiter.Acquire(permitCount: 1);
if (lease.IsAcquired)
{
  // Do action that is protected by limiter
}
else
{
  // Error handling or add retry logic
}
```

В данном случае мы пытаемся получить 1 разрешение с помощью метода _Acquire_\. Далее идёт проверка – было ли получено разрешение:

* если разрешение было получено, то можем использовать ресурс;
* если разрешение не было получено, то это можно залогировать или обработать как ошибку\.

## Встроенная поддержка контейнеров

Теперь можно быстро и легко создавать контейнерные версии своих приложений, используя команду _dotnet publish_\. 

Например:

```cpp
dotnet add package Microsoft.NET.Build.Containers
dotnet publish --os linux --arch x64 -c Release 
-p:PublishProfile=DefaultContainer
```

В данном случае мы добавляем временную ссылку на пакет для создания контейнера и публикуем проект для linux x64\. Результатом выполнения команд является образ, который будет добавлен в Docker\. После этого вы можете запустить приложение, используя контейнер:

```cpp
docker run -it --rm -p 5010:80 my-awesome-container-app:1.0.0
```

Подробнее про это можно почитать [здесь](https://devblogs.microsoft.com/dotnet/announcing-builtin-container-support-for-the-dotnet-sdk/)\.

## Улучшение производительности

Из года в год в \.NET растёт производительность\. Этот релиз не стал исключением\. Только на перечисление всех улучшений нужна отдельная статья, поэтому расскажу только о самых интересных\. 

Если интересны подробности улучшения производительности в \.NET 7, можете почитать о них [здесь](https://devblogs.microsoft.com/dotnet/performance_improvements_in_net_7/)\.

### Рефлексия

Существенно сокращены накладные расходы на использование рефлексии, когда вызов выполняется несколько раз для одного и того же элемента \(будь то метод, конструктор или свойство\)\. Производительность увеличена в 3\-4 раза\.

Подробнее про улучшение рефлексии можно прочитать [здесь](https://devblogs.microsoft.com/dotnet/performance_improvements_in_net_7/#reflection)\.

### LINQ

В \.NET 7 повышена производительность LINQ\. Например, была существенно улучшена эффективность методов _Min_ и _Max_ при работе с массивами типа _int_ и _long_\. Это достигается за счёт векторизации обработки, а именно – использования _Vector<T\>_\. В итоге получаются следующие результаты:

![1009_Whats_New_In_NET7_ru/image2.png](https://import.viva64.com/docx/blog/1009_Whats_New_In_NET7_ru/image2.png)

Подробнее про улучшения производительности LINQ можно прочитать в нашей [статье](https://pvs-studio.ru/ru/blog/posts/csharp/1011/)\.

Кстати, ещё очень здорово, что в _System\.Linq_ добавили новые методы _Order_ и _OrderDescending_\. Ранее при использовании _OrderBy/OrderByDescending_ было необходимо ссылаться на собственное значение:

```cpp
var data = new[] { 2, 1, 3 };
var sorted = data.OrderBy(x => x);
var sortedDesc = data.OrderByDescending(x => x);
```

Теперь же это не нужно:

```cpp
var data = new[] { 2, 1, 3 };
var sorted = data.Order();
var sortedDesc = data.OrderDescending();
```

### Регулярные выражения

Сначала я хотел кратко рассказать про улучшения в регулярных выражениях, но в ходе работы над статьёй пришло осознание того, что улучшений слишком много\. Поэтому просто оставлю ссылку на большую [статью](https://devblogs.microsoft.com/dotnet/regular-expression-improvements-in-dotnet-7/), посвящённую этой теме :\)\. Она в полной мере описывает все нововведения и улучшения регулярных выражений\. Здесь же отмечу, что Microsoft не только подняли производительность, но и добавили различные функциональные улучшения\.

## Заключение

Как видно, улучшений в \.NET 7 довольно много\. Не все из них одинаково полезны для всех разработчиков, но многие технологии продолжат своё развитие в рамках будущих выпусков \.NET\.

Лично для себя могу выделить как наиболее интересные и полезные:

* естественно, C\# 11;
* on stack replacement \(OSR\);
* централизованное управление пакетами \(CPM\);
* GC Regions\. 

Естественно, в статье были перечислены не все новшества, а только самые интересные \(по нашему мнению\)\. Со всеми улучшениями вы можете ознакомиться [здесь](https://devblogs.microsoft.com/dotnet/announcing-dotnet-7/)\. 

Используете ли вы уже что\-то из фишек нового \.NET? Пишите в комментариях\.