Окончательная версия выйдет уже в ноябре, а пока приглашаем под кат, где к старту нашего курса по разработке на 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. Вы также можете скачать последнюю предварительную версию .NET 7. После установки вы сможете сами оценить новые функции. Для этого создайте или откройте проект в C# и задайте тегу LangVersion значение Preview.
Предварительная версия Visual Studio приближает нас к полному набору функций C# 11. При разработке новой версии языка мы продолжаем вкладываться в развитие различных аспектов. По вашим отзывам мы внесли корректировки, а теперь — самое время скачать предварительную версию Visual Studio, протестировать новые функции и рассказать нам, что вы думаете о ней. Мы внимательно слушаем вас, пока работаем над окончательными версиями обновлений C# 11 и .NET 7.
Стать востребованным профессионалом в IT с самого начала или прокачаться помогут наши курсы. Скидка 45% по промокоду HABR:
ссылка на оригинал статьи https://habr.com/ru/company/skillfactory/blog/686880/


Добавить комментарий