Предварительная версия C# 11: обощённые типы для ML, обязательные члены и многое другое

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.


Окончательная версия выйдет уже в ноябре, а пока приглашаем под кат, где к старту нашего курса по разработке на C# рассказываем о новой предварительной версии и напоминаем, что у вас есть возможность повлиять на развитие языка.




C# 11 уже близится к завершению. Этот пост посвящён функциям версии Visual Studio 17.3 или тем функциям, которые не освещались в апрельском и февральском выпусках Visual Studio.


Новинки предварительной версии сводятся к трём основным аспектам, на которые мы обращаем особое внимание при разработке C# 11:


  • Улучшенная инициализация объектов: поддержка конструкторов и инициализаторов объектов стала проще при любых правилах для модифицируемых и немодифицируемых членах. Вот элементы новой функциональности языка:
  • Обязательные члены (ключевое слово required).
  • Поля ref.
  • Поддержка универсальной математики: вы можете использовать один написанный вами алгоритм со многими числовыми типами. Это упрощает сбор статистики, машинное обучение и другие прикладные задачи C# и .NET, требующие внушительного объёма вычислений. В том числе предлагаются:
  • Статические члены интерфейса: абстрактные и виртуальные.
  • Ослабление требований к сдвигу вправо.
  • Оператор беззнакового сдвига вправо.
  • Числовой оператор IntPtr.
  • Продуктивность разработчика: новые возможности языка сделают вашу работу продуктивнее. В первую очередь расширена область применения nameof.

Все эти функции описаны ниже со ссылками на разделы документации, где вы можете узнать о них больше. Чтобы протестировать эти возможности, включите в своём проекте функцию предварительного просмотра. Объяснения приводятся в статье «Новые возможности C# 11».


Улучшенная инициализация объектов


Обязательные члены позволяют записывать типы классов и структур с требуемыми операторами вызова. Вот, например, тип Person:


public class Person
{
    public string FirstName { get; init; }
    public string LastName {get; init; }
}

Операторы вызова должны иметь инициализаторы объектов, которые задают свойства FirstName и LastName. До версии 17.3 компилятор не мог заставить операторы вызова устанавливать эти свойства, тогда как конструктор с обязательными параметрами — единственный способ убедиться в том, что пользователь задал свойства FirstName и LastName. Ключевое слово required сообщает компилятору и операторам вызова, что свойства должны быть заданы:


public class Person
{
    public required string FirstName { get; init; }
    public required string LastName {get; init; }
}

Все операторы вызова должны включать инициализаторы объектов свойств FirstName и LastName, иначе компилятор сообщает, что обязательные члены не заданы, и выдаёт ошибку. Таким образом, разработчик решит эту проблему сразу, а не будет возвращаться к ней на этапе сдачи проекта.


Если тип Person использовался с компилятором прошлых версий и включает конструктор для задания свойств, это не помешает вам использовать обязательные члены. Для их применения существующие конструкторы должны использовать атрибут SetsRequiredMembers:


public class Person
{
    public required string FirstName { get; init; }
    public required string LastName {get; init; }

    [SetsRequiredMembers]
    public Person(string firstName, string lastName)
    {
        this.FirstName = firstName;
        this.LastName = lastName;
    }

    public Person() {}
}

Атрибут SetsRequiredMembers требует от конструктора задать все обязательные параметры. Компилятор узнаёт, что Person(string firstName, string lastName) — это параметры, задать которые необходимо. Конструктор без параметров не включает и этот атрибут, поэтому для операторов вызова, использующих этот конструктор, нужно инициализировать все обязательные члены.


В примерах выше изменения касались свойств. Но обязательные члены применимы и к объявлению полей.


В предварительной версии в начальном виде реализованы также значения полей ref и scoped. Теперь поля ref можно использовать в типах ref struct. Ключевое слово scoped позволяет ограничить время жизни параметров ref. На данный момент описания функций и изменений в новой версии — лучшая доступная документация по этой теме. Мы обнаружили несколько ситуаций, где для безопасного применения новой фичи потребовались обновления языка. Эти обновления появятся в более поздней предварительной версии, а документация по ней будет отражать функциональность окончательной версии.


Поддержка математики с обобщёнными типами


Добавлен ряд функций для поддержки математики с обобщёнными типами. Новая функциональность, вероятно, пригодятся вам только в сложных ситуациях с написанием алгоритмов, которые должны работать с разными типами чисел. Но, даже если вы не пишете таких алгоритмов, то сможете извлечь косвенную выгоду, ведь среда выполнения использует функциональность из списка ниже:


  • Статические члены интерфейса: абстрактные и виртуальные.
  • Ослабление требований к сдвигу вправо.
  • Оператор беззнакового сдвига вправо.
  • Числовой оператор IntPtr.

Появление в интерфейсе статических абстрактных и виртуальных членов коснётся большей части расчётов с обобщёнными типами. Они позволяют объявлять операторы и другие статические методы прямо из интерфейса. Классы, реализующие интерфейс, должны поддерживать static abstract и другие заявленные в интерфейсах методы.


Компилятор разрешает вызовы методов static, включая операторы, во время компиляции. При этом механизма динамической диспетчеризации, как для методов экземпляра, в этом случае нет. В доках конкретные правила записи этой функции объясняются подробнее.


Другие возможности языка сглаживают некоторые различия числовых типов и облегчают написание обобщённых математических алгоритмов. Оператор сдвига вправо больше не требует, чтобы второй операнд имел тип int. Подойдёт любой целочисленный тип данных! Типы nint и nuint — это синонимы System.IntPtr и System.UIntPtr соответственно. Вместо соответствующих типов можно использовать эти ключевые слова, а новые анализаторы позволяют и даже побуждают делать это. Наконец, оператор беззнакового сдвига вправо (>>>) позволяет избежать приведения типа при выполнении беззнакового сдвига.


Эти и другие изменения повлияли на работу математики с обобщёнными типами в рантайме. К другим изменениям относятся, например, пользовательские операторы с проверкой переполнения. Улучшения языка позволяют команде рантайма эффективнее использовать все числовые типы .NET. Эти возможности пригодятся и в реализации контрактов с помощью операторов или других статических методов.


Продуктивность разработчиков


Теперь оператор nameof можно применять вместе с параметрами методов. То есть вы можете использовать оператор nameof при объявлении атрибутов метода:


[return: NotNullIfNotNull(nameof(url))]
string? GetTopLevelDomainFromFullUrl(string? url)

Попробуйте сами


Предлагаем вам скачать предварительные версии Visual Studio 2022. Вы также можете скачать последнюю предварительную версию .NET 7. После установки вы сможете сами оценить новые функции. Для этого создайте или откройте проект в C# и задайте тегу LangVersion значение Preview.


Предварительная версия Visual Studio приближает нас к полному набору функций C# 11. При разработке новой версии языка мы продолжаем вкладываться в развитие различных аспектов. По вашим отзывам мы внесли корректировки, а теперь — самое время скачать предварительную версию Visual Studio, протестировать новые функции и рассказать нам, что вы думаете о ней. Мы внимательно слушаем вас, пока работаем над окончательными версиями обновлений C# 11 и .NET 7.


Стать востребованным профессионалом в IT с самого начала или прокачаться помогут наши курсы. Скидка 45% по промокоду HABR:


  • Профессия C#-разработчик (12 месяцев)
  • Профессия Data Scientist (24 месяца)

Скидка 45% по промокоду HABR

Источник: https://habr.com/ru/company/skillfactory/blog/686880/


Интересные статьи

Интересные статьи

.NET Conf 2021 была крупнейшей .NET Conf когда-либо с более чем 80 сессиями от докладчиков со всего мира! Мы хотим сказать огромное спасибо всем, кто выступил в прямом эфире, задавал вопросы в ленте T...
Пару дней назад 0xd34df00d опубликовал здесь перевод статьи, описывающей, что можно узнать о функции в разных языках, если рассматривать её как "чёрный ящик", не используя информацию о её реализа...
5-6 апреля, то есть уже на этих выходных, пройдёт JPoint 2019 — международная Java-конференция для опытных Java-разработчиков. Если вы не смогли поучаствовать, вживую или онлайн, то у нас есть ...
Одной из «киллер-фич» 12й версии Битрикса была объявлена возможность отдавать статические файлы из CDN, тем самым увеличивая скорость работы сайта. Попробуем оценить практический выигрыш от использова...