Какие полезные функции появились в последних версиях C#?

Ответ

В C# 10 и 11 появилось несколько важных функций, повышающих продуктивность и читаемость кода.

Ключевые нововведения:

  • Record structs (C# 10): Иммутабельные структуры с автоматически генерируемыми методами Equals, GetHashCode и ToString. Идеальны для небольших данных, передаваемых по значению.

    public readonly record struct Point(int X, int Y);
    var p1 = new Point(1, 2);
    var p2 = p1 with { X = 3 }; // Новая запись с измененным X
  • Global using directives (C# 10): Позволяют объявить директиву using один раз для всего проекта, убирая её из каждого файла.

    // GlobalUsings.cs
    global using System;
    global using System.Collections.Generic;
  • File-scoped namespaces (C# 10): Упрощает объявление пространства имён, уменьшая отступы во всём файле.

    namespace MyApp.Services; // Фигурные скобки для всего файла не нужны
    public class UserService { ... }
  • Улучшения pattern matching (C# 10/11): Расширенные реляционные паттерны и паттерны в списках.

    bool IsLetter(char c) => c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z');
  • Raw string literals (C# 11): Удобны для записи JSON, XML, SQL или многострочного текста без экранирования кавычек.

    string json = """
    {
        "name": "John",
        "age": 30
    }
    """;
  • Required members (C# 11): Гарантирует инициализацию свойств или полей при создании объекта.

    public class Person
    {
        public required string FirstName { get; init; }
        public required string LastName { get; init; }
    }
    // new Person(); // Ошибка компиляции
    var p = new Person { FirstName = "John", LastName = "Doe" }; // OK

Ответ 18+ 🔞

Да ты посмотри, какие штуки нам в C# 10 и 11 подкинули! Прям как будто разработчики наконец-то услышали, как народ матерится на велосипеды из костылей, которые раньше приходилось собирать. Серьёзно, некоторые фичи — просто бальзам на душу.

Что там нового, на что стоит глаз положить:

  • Record structs (C# 10): Ну наконец-то, блядь! Раньше record'ы были только классами, а теперь и для структур сделали. Иммутабельные такие, легковесные, для мелких данных — идеально. Методы Equals, GetHashCode и ToString сами генерируются, как по маслу. Хочешь копию с одним изменённым полем? Без проблем, with выражение и работает.

    public readonly record struct Point(int X, int Y);
    var p1 = new Point(1, 2);
    var p2 = p1 with { X = 3 }; // Всё, новая запись, X поменял
  • Global using directives (C# 10): Вот это, я тебе скажу, просто праздник какой-то. Устал уже в каждом файле писать using System;? Теперь можно один раз в проекте объявить — и всем файлам хватит. Чистота, порядок, глаз не мозолит.

    // GlobalUsings.cs — один файл на весь проект
    global using System;
    global using System.Collections.Generic;
  • File-scoped namespaces (C# 10): А это вообще гениально просто. Раньше весь код уезжал на один отступ внутрь из-за фигурных скобок namespace'а. А теперь? Объявил пространство имён в одну строку — и всё, пиши код с первого столбца. Удобство — овердохуища.

    namespace MyApp.Services; // И всё! Фигурных скобок для namespace не нужно
    public class UserService { ... } // Пишем сразу тут
  • Улучшения pattern matching (C# 10/11): Паттерны так разошлись, что теперь в них можно почти всю логику проверок упаковать. Реляционные паттерны (>=, <) прямо в is проверке, комбинирование через and/or — красота.

    bool IsLetter(char c) => c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z');
    // Читается же, как обычное предложение: "символ — это от a до z ИЛИ от A до Z"
  • Raw string literals (C# 11): О, это моя любимая тема! Наконец-то можно JSON, XML или SQL в код вставлять без этого цирка с экранированием кавычек и конкатенацией строк. Три двойные кавычки — и пиши внутри что угодно, хоть сотню строк.

    string json = """
    {
        "name": "John",   // Смотри, никаких "
        "age": 30
    }
    """;
    // Компилятор, блядь, сам отступы умные уберёт. Вообще красота.
  • Required members (C# 11): А вот это жёстко. Раньше можно было забыть инициализировать важное свойство — и получал null где-нибудь в глубине логики. Теперь пометил поля или свойства как required — и компилятор тебе не даст создать объект, пока ты их все явно не проинициализируешь. Принудительная дисциплина, но она к месту.

    public class Person
    {
        public required string FirstName { get; init; } // Обязательное!
        public required string LastName { get; init; }  // Тоже!
    }
    // new Person(); // Не скомпилируется, скажет: "Чувак, ты FirstName и LastName забыл!"
    var p = new Person { FirstName = "John", LastName = "Doe" }; // Вот так — правильно.

В общем, ребята из команды C# явно не сидят сложа руки. Какие-то мелочи, а сколько нервов экономят. Прям чувствуется, что язык взрослеет и умнеет, а не просто синтаксическим сахаром обрастает.