.NET 10 приїхав! Що нам привезли в новій LTS-ці та Visual Studio 2026

💡 Усі статті, обговорення, новини про .NET — в одному місці. Приєднуйтесь до .NET спільноти!

Що ж, дочекалися. Microsoft на .NET Conf 2025 офіційно викотила .NET 10. Це нова LTS-ка (версія з довгостроковою підтримкою), а отже, з нами вона надовго — підтримка триватиме три роки. Разом з нею випустили і Visual Studio 2026, яку обіцяють зробити нарешті швидшою та зручнішою.

Я пробігся по головних анонсах і технічних доповідях. І, чесно кажучи, цього разу змін дуже багато. Давайте дивитися.

C# 14: Нарешті знову цікаво!

Почнемо з мови. C# 14 — це, мабуть, один з найзначніших релізів за останній час.

1. Extension Members (Моя улюблена фіча)

Ми жили з extension-методами з C# 3.0. Це було корисно, але синтаксис завжди був трохи незграбним. Тепер це виглядає набагато чистіше.

Раніше ми писали так:

public static class StringExtensions
{
    public static bool IsNullOrEmpty(this string value)
    {
        return string.IsNullOrEmpty(value);
    }
}

Тепер можна групувати логіку в extension блок:

public static class StringExtensions
{
    // Оголошуємо тип і "змінну" один раз
    extension(string value)
    {
        public bool IsNullOrEmpty()
        {
            return string.IsNullOrEmpty(value);
        }
        public string Truncate(int maxLength)
        {
            if (string.IsNullOrEmpty(value) || value.Length <= maxLength)
                return value;
            return value.Substring(0, maxLength);
        }
    }
}

Але це ще не все! Тепер можна додавати extension-властивості. Це просто знахідка для читабельності коду. Наприклад, замість !items.Any():

public static class CollectionExtensions
{
    extension<T>(IEnumerable<T> source)
    {
        public bool IsEmpty => !source.Any();
        public bool HasItems => source.Any();
    }
}
// І в коді:
if (orders.IsEmpty) // Як же цього не вистачало!
{

Console.WriteLine("No orders to process«);

}

Всередині extension блоку можна навіть оголошувати private поля для кешування. Це взагалі топ.

extension<T>(IEnumerable<T> source)
{
    private List<T>? _materializedList;
    public List<T> MaterializedList => _materializedList ??= source.ToList();
    public bool IsEmpty => MaterializedList.Count == 0;
}

А ще завезли статичні extension-члени для фабричних методів. Можна буде писати Product.CreateDefault() замість new Product(...) у коді. Дуже круто.

2. Ключове слово field

Нарешті нам не потрібно оголошувати _backingField вручну!

Раніше:

public class Record
{
    private string _msg;
    public string Message
    {
        get => _msg;
        set => _msg = value ?? throw new ArgumentNullException(nameof(value));
    }
}

Тепер:

public class Record
{
    public string Message
    {
        get;
        // "field" - це згенероване компілятором поле
        set => field = value ?? throw new ArgumentNullException(nameof(value));
    }
}

Це особливо зручно для лінивої ініціалізації:

public Dictionary<string, string> ConfigValues
{
    // Ідеально для get-only властивостей з дефолтом
    get => field ??= new Dictionary<string, string>();
    set => field = value;
}

3. Null-Conditional Assignment

Про це я вже казав, але тепер це офіційно. Замість:

if (user is not null)
{
    user.Profile = LoadProfile();
}

Пишемо:

user?.Profile = LoadProfile();

Дрібниця, а код чистить неймовірно.

4. Інші дрібні покращення

  • Модифікатори в лямбдах: Тепер можна писати (text, out result) => ... без явного вказування типів (string text, out int result). Маленьке, але логічне покращення.
  • Часткові (partial) конструктори та івенти: Це в основному для авторів source-генераторів, але дає їм більше гнучкості.

Головна зміна в .NET 10: «Файлові» застосунки

Ось це, як на мене, найбільша зміна в екосистемі. Вона повністю змінює підхід до скриптів та маленьких утиліт.

Раніше, щоб написати «Hello World», треба було:

  1. dotnet new console
  2. Отримати sln, csproj і Program.cs
  3. dotnet run

Тепер можна просто створити один файл main.cs і виконати:

dotnet run main.cs

Це ставить C# в один ряд з Python, JS та іншими скриптовими мовами. Написати утиліту для CI/CD чи автоматизації тепер можна без усього цього проектного «сміття».

Але як бути з пакетами? Дуже просто — через #: директиви:

// main.cs
#:sdk Microsoft.NET.Sdk.Web
#:package [email protected]
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder();
builder.Services.AddDbContext<OrderDbContext>(options =>
{
    options.UseSqlite("Data Source=orders.db");
});
var app = builder.Build();
app.MapGet("/orders", async (OrderDbContext db) =>
{
    return await db.Orders.ToListAsync();
});
app.Run();
// ... (визначення Order та OrderDbContext) ...

Ви тільки подивіться! Minimal API з EF Core в одному файлі! Це ж просто фантастика для прототипів. Можна посилатися і на існуючі проекти:

#:project ../ClassLib/ClassLib.csproj. 

A для Unix-систем можна писати повноцінні shell-скрипти:

#!/usr/bin/env dotnet 
Console.WriteLine("Hello from C# script!"); 
chmod +x app.cs ./app.cs

А коли ваш скрипт виросте, його можна легко конвертувати у повноцінний проект: dotnet project convert app.cs. Це дуже розумний хід.

ASP.NET Core 10

Тут теж багато хорошого.

  • Вбудована валідація в Minimal APIs: Нарешті! builder.Services.AddValidation() — і ваші параметри та тіла запитів (включно з record) валідуються автоматично через DataAnnotations. Повертає 400 Bad Request, як і має бути. Це робить Minimal API ще на крок ближчими до повноцінних контролерів.
  • Server-Sent Events (SSE): Це дуже крута альтернатива WebSockets, коли вам потрібен потік даних тільки від сервера до клієнта (наприклад, для дашбордів, оновлення цін). Реалізовано дуже чисто через IAsyncEnumerable<T> і TypedResults.ServerSentEvents.
  • OpenAPI 3.1 та YAML: Підтримка OpenAPI 3.1 — це важливо для сумісності з JSON Schema. А можливість генерувати openapi.yaml замість JSON порадує багатьох фронтенд-розробників, бо YAML чистіший.
  • JSON Patch: Додали підтримку JSON Patch для System.Text.Json.

EF Core 10

Тут дві головні фічі, і обидві довгоочікувані.

1. Комплексні типи (Complex Types)

Це, мабуть, головна фіча EF Core 10. Вона дозволяє моделювати дані, які є частиною сутності, але не мають власного ключа.

  • Table Splitting: Ви можете зберігати ShippingAddress і BillingAddress як колонки в таблиці Customer (Street, City і т.д.).
  • JSON Mapping: Або ж ви можете просто «запакувати» весь об’єкт Address в одну JSON-колонку в базі даних: b.ComplexProperty(c => c.ShippingAddress, c => c.ToJson());.

Це дає неймовірну гнучкість, дозволяючи поєднувати реляційний підхід із документо-орієнтованим. І так, це працює зі структурами (struct)!

2. Оператори LeftJoin та RightJoin

СТІЛЬКИ РОКІВ ЧЕКАНЬ! Більше ніяких страшних GroupJoin, SelectMany і DefaultIfEmpty для того, щоб зробити звичайний LEFT JOIN.

Тепер можна просто і зрозуміло написати:

var query = context.Students
.LeftJoin(
context.Departments,
student => student.DepartmentID,
department => department.ID,
(student, department) => new { /* ... */ });

Це просто свято для читабельності коду.

Blazor

Тут теж є приємні покращення:

  • Hot Reload для Blazor WebAssembly (та .NET на WebAssembly).
  • Профілювання продуктивності для WASM.
  • Параметр NotFoundPage для роутера.
  • Попереднє завантаження (preloading) статичних асетів у Blazor Web Apps.

Загалом, хороші QoL-покращення, особливо Hot Reload для WASM.

Під капотом: Перформанс і Runtime

Як завжди, .NET став ще швидшим.

  • Постквантова криптографія: Це найцікавіше. В System.Security.Cryptography додали підтримку трьох постквантових алгоритмів (ML-KEM, ML-DSA, SLH-DSA). Це інвестиція в майбутнє, щоб дані, зашифровані сьогодні, не можна було зламати квантовими комп’ютерами завтра.
  • Підтримка AVX10.2: .NET 10 вже готовий до нових процесорів, які з’являться наступного року.
  • Масиви у стеку: JIT-компілятор тепер достатньо розумний, щоб малі масиви (навіть string[]) розміщувати в стеку. Це знижує навантаження на GC.
  • Оптимізація GC та JIT-компілятора (кращий інлайнінг, менше навантаження).

Visual Studio 2026

Сама IDE теж отримала апгрейд. Обіцяють:

  • Миттєвий запуск (на рівні VS Code).
  • Оновлений, чистіший інтерфейс.
  • Прискорення збірки до 25%.
  • Покращений Hot Reload.

Вердикт

Якщо .NET 8 був солідним LTS, то .NET 10 — це просто величезний стрибок.

«Файлові» застосунки повністю змінюють правила гри для скриптингу. C# 14 з новими extension та field робить код набагато чистішим. А LeftJoin та «комплексні типи» в EF Core — це те, чого ми просили роками.

Це зрілий, швидкий і неймовірно потужний реліз. Час оновлюватися!

👍ПодобаєтьсяСподобалось13
До обраногоВ обраному2
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

i think i dont need this for clean code best regards marcin scholke

but good to know and You can code this way if You want nobody steal Your code :)

.NET 10 — це просто величезний стрибок

Вы серьезно?

Головна зміна в .NET 10: «Файлові» застосунки

Це є з .net 5
для F#

Це ставить C# в один ряд з Python, JS та іншими скриптовими мовами

🤦🤦‍♀️🤦‍♂️

нажаль, попри всі заяви майків шо всі 3 мови дотнета рівноціні, на практиці шарп вважається дефолт мовою.
багато хто взагалі не згадує про існування фаршу і бейсіка 🤷‍♂️

Про бейсік не варто i згадувать

для «дефолтнної мови» скіптинг був у mono, ще раніше, може років 15 тому.

не користалися? звісно, бо воно нах. нікому не потрібно було
а тепер — ба: Головна зміна в .NET 10!

для «дефолтнної мови» скіптинг був у mono, ще раніше, може років 15 тому.

ото ти старий!

🤦🤦‍♀️🤦‍♂️

Ну а якщо відкинути релігію і стереотипи, чого ще не хватає? Ну крім екосистеми різного роду бібліотек. Но чисто функціонально, не сильно відрізняється від

Python, JS

в плані розробки і запуску скриптів

шарп скрипти всеодно компілюються.
може бути проблема якшо в юзера немає прав запису.
пітон і яваскрит запустяться. дотнет — ні

шарп скрипти всеодно компілюються.

та пофіг, це все вібувається під капотом, в гіршому випадку холодний старт буде гірший ніж у js, але не гірший ніж у пітона, але в любому випадку ним можна нехтувати, це не так важливо для скриптів.

може бути проблема якшо в юзера немає прав запису.

та воно в якийсь temp в user profile компілиться, важко уявити що у юзера не буде прав, а якщо не буде, то не буде прав запускати рандомний js код тим більше

важко уявити що у юзера не буде прав

права можуть бути, а от місця вже ні 😉

але вцілому я згоден. скріпти на шарпі/фарші це добре.

та ваще насрать, ніхто це в здоровому глузді не робить на енвах окрім ділдів бумерів та наркоманів, вже давно білди ранаються в докері і заливається вже докер імейдж на енв. ото іще лазити на енв машину і туди щось заливати, вже забув коли таке робив, мать в 14-му останній раз. зараз запушив коміт і запустився пайплайн автоматично що білдить та заливає код. хоч ажур девопс хоч гитхаб єкшен хоч гіт лаб. деплоймент то девопсяча робота.

Ну а якщо відкинути релігію і стереотипи, чого ще не хватає?

ну напишіть скрипт, який відсилає alert, або лист, коли закінчилось місце на диску
або скрипт, який встановить dotnet під час деплою на нову ноду

я звісно писати не буду, але в чому принципіальна проблема написати таке?

бо це все частина девопсі, інфраструктурі та клауду і вона не залежно від платформи розробки. ніхто в здоровому глузді не тримає прод систему котра від дотнет\нод_модулів білда может вижрати диск і стопнути машину. це взагалі страшилки якісь, ліл.

так а в чому проблема? не важче ніж написати скрипт на пітоні який установить пітон на нову ноду, чи скрипт на js який установить nodejs )

Оце супер — файлові застосунки та лефт джойн не пройшло і 30 років!!! Усе інше (чисто по мові) в принципі пофік якось, сахарь звичайний, not great not terrible.

Підписатись на коментарі