Что нового в C # 10: обзор
В этой статье рассматривается новая версия языка C # — C # 10. По сравнению с C # 9, C # 10 включает небольшой список улучшений. Ниже мы описали улучшения и добавили пояснительные фрагменты кода. Посмотрим на них.

Улучшения структурных типов
Инициализация структуры поля
Теперь вы можете настроить инициализацию полей и свойств в структурах:
Объявление конструктора без параметров в структурном типе
Начиная с C # 10, вы можете объявлять конструктор без параметров в структурах:
Важно. Вы можете использовать конструкторы без параметров, только если все поля и / или свойства имеют инициализаторы. Например, если вы не установите инициализатор Age, компилятор выдаст ошибку:
Ошибка CS0843: автоматически реализуемое свойство User.Age должно быть полностью присвоено, прежде чем управление будет возвращено вызывающей стороне.
Применение выражения with к структуре
Раньше вы могли использовать выражение with с записями. В C # 10 это выражение можно использовать со структурами. Пример:
Понятно, что свойство, которое мы изменяем (в данном случае поле Name), должно иметь модификатор общего доступа.
Глобальное использование
Начиная с C # 10, вы можете использовать директиву using во всем проекте. Добавьте ключевое слово global перед фразой using:
Таким образом, директива using позволяет не дублировать одни и те же пространства имен в разных файлах.
Важно. Используйте конструкцию global using ПЕРЕД строками кода, которые включают using без ключевого слова global. Пример:
Если вы написали пространство имен, которое ранее было записано с помощью ключевого слова global, среда IDE предупредит вас (IDE: 0005: использование директивы не требуется).
Пространство имен в области файлов
Иногда вам нужно использовать пространство имен во всем файле. Это действие может сместить вкладки вправо. Чтобы избежать этой проблемы, теперь вы можете использовать ключевое слово namespace. Напишите ключевое слово namespace без фигурных скобок:
До C # 10 необходимо было держать открытыми фигурные скобки namespace для всего файла:
Очевидно, что в файле можно объявить только одно пространство имен. Соответственно, следующий фрагмент кода неверен:
а также следующий фрагмент кода:
Улучшения записи
Ключевое слово класса
C # 10.0 вводит необязательное ключевое слово — class. Ключевое слово class помогает понять, относится ли запись к ссылочному типу.
Таким образом, две следующие записи идентичны:
Структуры записи
Теперь можно создавать структуры записей:
По умолчанию свойства структуры записи являются изменяемыми, в отличие от стандартной записи, у которой есть модификатор init.
Мы можем установить свойство readonly для структуры записи. Тогда доступ к полям будет эквивалентен стандартной записи:
где свойства записываются как:
Равенство двух структурных объектов записи аналогично равенству двух структур. Равенство истинно, если эти два объекта хранят одинаковые значения:
Обратите внимание, что компилятор не синтезирует конструктор копирования для типов структур записей. Если мы создадим конструктор копирования и будем использовать ключевое слово with при инициализации нового объекта, то вместо конструктора копирования будет вызываться оператор присваивания (как это происходит при работе с классом записи ).
Запечатать метод ToString () для записей
Как писал мой коллега в статье Улучшения для C # 9, записи имеют переопределенный метод toString. Есть интересный момент наследования, связанного с этим методом. Дочерние объекты не могут наследовать переопределенный метод toString от родительской записи. В C # 10 введено ключевое слово sealed, чтобы дочерние объекты могли наследовать метод ToString. Это ключевое слово не позволяет компилятору синтезировать реализацию ToString для любых производных записей. Используйте следующее ключевое слово, чтобы переопределить метод ToString:
Давайте создадим запись, которая пытается переопределить метод toString:
Теперь унаследуем вторую запись:
Теперь давайте создадим экземпляр каждой записи и введем результат в консоль:
Как мы видим, InheritedRecord не унаследовал метод toString.
Давайте немного изменим запись TestRec и добавим ключевое слово sealed:
Теперь давайте воссоздадим два экземпляра записей и введем результат в консоль:
И .. ууууу! InheritedRecord унаследовал метод toString от TestRec.
Упрощенный доступ к вложенным полям и свойствам шаблонов свойств
В C # 8.0 введен шаблон свойств, который позволяет легко сопоставлять поля и / или свойства объекта с необходимыми выражениями.
Раньше, если вам нужно было проверить какое-либо вложенное свойство, код мог выглядеть слишком громоздким:
В C # 10 вам просто нужно добавить точки между свойствами:
Давайте посмотрим на изменение на примере метода взятия первых 4 символов имени.
Приведенный выше пример показывает, что новый тип доступа к свойствам проще и понятнее, чем раньше.
Постоянные интерполированные строки
Раньше эта функция не поддерживалась. C # 10 позволяет использовать строковую интерполяцию для постоянных строк:
Интересный факт. Это изменение касается только строковой интерполяции для константных строк, т.е. добавление константного символа не допускается:
Присвоение и объявление в одной деконструкции
В более ранних версиях C # деконструкция могла присваивать значения ЛИБО объявленным переменным (все они объявлены) ИЛИ переменным, которые мы инициализируем во время вызова (все НЕ объявляются):
Новая версия языка позволяет одновременно использовать при деконструкции как ранее объявленные, так и необъявленные переменные:
В версии C # 9 произошла следующая ошибка:
Ошибка CS8184: деконструкция не может смешивать объявления и выражения слева.
Заключение
Как упоминалось ранее, список изменений не такой большой, как в версии C # 9. Некоторые изменения упрощают работу, а другие предоставляют ранее недоступные функции. C # все еще развивается. Мы с нетерпением ждем новых обновлений языка C #.
Еще не читали о новых функциях C # 9? Ознакомьтесь с ними в нашей отдельной статье.
Если вы хотите увидеть первоисточник, вы можете прочитать Документацию Microsoft.
A Closer Look at 5 New Features in C# 10
Global using, file-scoped namespaces, and other enhancements will slim down unnecessary code
![]()
![]()
UPDATE: C# 10 is now released, and you can get the final word about what made it in — and what didn’t — over here.
W e’ve been speculating about the future of C# 10 for a while. The possibilities are no secret. Spend some time on the C# GitHub page and you’ll find a long list of tantalizing ideas — some with major headaches still being hashed out. Many of them won’t make it into the next version of C#, and some of them won’t appear in the language ever. (There’s a high bar to get into C#, because the language mandates that once a keyword or syntactical structure is supported, its behavior should never change in a breaking way for the rest of all eternity.)
If you want to know what’s actually confirmed for C# 10, you could wait for the language to be released in November along with .NET 6. Or, you could follow the fine people on the C# team as they demonstrate their favorite features. Last week at Microsoft’s Build conference, lead C# designer Mads Torgersen pulled the covers off some of the work that’s currently underway. Here are five new features you’ll see in the next release of the language.
1. Global usings
A typical C# source code file begins with a pile of namespace imports. Here’s a snippet from an ordinary ASP.NET web application:
There’s nothing objectionable about this arrangement. But once upon a time, the namespace imports gave us a quick idea of what libraries a class was using. Today, it’s become just another block of boilerplate for us to…
Обзор нововведений в C# 10
В данной статье мы рассмотрим новую версию языка C# 10, которая включает в себя небольшой список изменений относительно C# 9. Ниже приведены их описания вместе с поясняющими фрагментами кода. Давайте их рассмотрим.

Изменения структур
Инициализация полей структуры
Теперь в структурах можно задать инициализацию полей и свойств:
Объявление конструктора структуры без параметров
В C# 10 станет доступно создание конструктора без параметров для структур:
Важно. Использовать конструктор без параметров можно только тогда, когда все поля и/или свойства имеют инициализаторы. Например, если не задать инициализатор Age, возникнет ошибка:
Error CS0843: Auto-implemented property ‘User.Age’ must be fully assigned before control is returned to the caller.
Применение выражения with к структуре
Новая версия C# делает доступным использование выражения with со структурами, как ранее это можно было сделать с записями. Пример:
Очевидно, что изменяемое свойство (в данном случае поле Name) должно быть с публичным модификатором доступа.
Глобальное использование using
Данное нововведение позволит использовать директиву using с охватом всего проекта. Для этого необходимо перед фразой using добавить ключевое слово global:
Таким образом, можно не дублировать в разных файлах одни и те же пространства имён, используя директиву using.
Важно. Применять данную конструкцию следует ПЕРЕД включениями using, которые объявлены без использования global. Пример:
Если произошло так, что вы повторно включили одно пространство имён при условии, что оно было ранее включено с использованием ключевого слова global, то об этом будет сообщено средой разработки (IDE: 0005: Using directive is unnecessary).
namespace для всего файла
Бывает такое, что пространство имён необходимо использовать во всём файле, но это может немного сдвинуть отступы текста программы. Теперь для решения этой проблемы добавлена возможность использования namespace для всего файла. Для этого необходимо написать namespace без использования блочных фигурных скобок:
Ранее необходимо было тянуть на весь файл открытый блок namespace:
Очевидно, указать в файле можно лишь один такого рода namespace. То есть данная запись некорректна:
как и запись такого вида:
Изменение записей
Ключевое слово class
В версии языка C# 10.0 было добавлено необязательное ключевое слово class у записей, которое лишь помогает при чтении кода определить принадлежность записи к ссылочному типу.
То есть две следующие записи идентичны:
Структуры записей
Также теперь можно создавать структуры записей:
По умолчанию, свойства данной записи можно изменять, в отличие от стандартной record, в которой модификатор изменения полей – init:
К данной структуре можно применить свойство readonly, тогда доступ к полям будет подобен обычной записи:
где свойства записаны как:
Равенство двух объектов структуры записей схоже с равенством двух обычных структур – равенство истинно, если эти два объекта хранят одни и те же данные:
Стоит отметить, что для структур записей не генерируется конструктор копирования. Если определить его и использовать ключевое слово with при инициализации нового объекта, то вызываться будет оператор присваивания, вместо конструктора копирования (как это происходит при работе с record class).
Запечатывание метода ToString
Как писал мой коллега в статье о нововведениях в C# 9, у записей имеется метод ToString, который можно переопределить. Но при наследовании есть одна особенность: переопределенный вами метод ToString не будет унаследован потомками от родительской записи. Для того чтобы потомки записей наследовали метод ToString, стало доступно использование ключевого слова sealed, которое запрещает компилятору генерировать имплементацию метода ToString у дочерних записей. Данное ключевое слово указывается при переопределении метода ToString:
Создадим следующую запись, включая переопределение метода ToString:
И наследуем от него вторую запись:
Теперь создадим по экземпляру каждой из записей и напечатаем результат в консоль:
Как видно из результата выше, метод ToString не был наследован записью InheritedRecord.
Немного изменим запись TestRec, добавив ключевое слово sealed:
Заново создадим два экземпляра записей и напечатаем результат в консоль:
И.. ура! Метод ToString был наследован в записи InheritedRecord.
Упрощение доступа к вложенным полям и свойствам шаблонных свойств
Версия языка C# 8.0 предоставила возможность использования шаблонных свойств, с помощью которых можно удобно сопоставлять поля и/или свойства какого-либо объекта с необходимыми значениями.
Ранее, если необходимо было проверить какое-либо вложенное свойство, то приходилось громоздить конструкцию:
Сейчас достаточно лишь привычного добавления точек между свойствами:
Рассмотрим изменение на примере метода взятия 4 первых символов имени.
Как видно из примера выше, новый тип обращения к свойствам проще и понятнее, чем был раньше.
Интерполирование константных строк
Ранее данная возможность не поддерживалась, но в новой версии языка C# можно будет интерполировать и константные строки:
Интересный факт. Данное нововведение относится к интерполированию строк, то есть добавление константного символа не допускается:
Одновременное использование объявленных и инициализируемых переменных при деконструировании
В старом варианте вызова деконструктора можно использовать ИЛИ объявленные переменные (все объявлены), ИЛИ переменные, которые мы инициализируем прямо при вызове (все НЕ объявлены):
Новая версия языка допускает одновременное использование как объявленных ранее, так и не объявленных переменных при деконструировании:
В версии C# 9 возникала ошибка:
Error CS8184: A deconstruction cannot mix declarations and expressions on the left-hand-side.
Заключение
Как говорилось ранее, список изменений не столь велик, как в версии C# 9. Одни изменения упрощают работу, а другие разблокируют ранее недоступные возможности. Развитие не стоит на месте, а мы будем ждать новых обновлений языка C#.
Если вы еще не ознакомлены с нововведениями версии C# 9, то о них мы тоже подробно рассказывали в отдельной статье.
Если вы хотите ознакомиться с первоисточником, можете прочесть документацию Microsoft.
Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Valentin Prokofiev. What’s new in C# 10: overview.
C 10 что нового
8 ноября компания Microsoft выпустила финальную версию фреймворка .NET 6.0 с C# 10 и F# 6, а также Visual Studio 2022. .NET 6 ознаменовался значительным увеличением поизводительности по сравнению с предыдущими версиями фреймворка и большим количеством нового функционала. Кроме того, это LTS-версия, которая будет поддерживаться в течении следующих трех лет.
.NET 6.0 представляет унифицированную платформу, которая позволяет создавать десктопные и мобильные и веб-приложения, а также приложения для IoT и облака.

Некоторые основные изменения в этой версии:
Благодаря внедрению Dynamic Profile-guided Optimization (PGO) удалось повысить производительность. Dynamic PGO базируется на механизме уровневой компиляции Tiered Compilation, которая позволяет произвести на старте быструю базовую компиляцию методов («уровень 0»), а когда метод потребует, произвести его перекомпиляцию с рядом оптимизаций («уровень 1»)
Полностью переписан API для работы с файлами, в частности, класс FileStream . Это привело к значительному увеличению производительности: увеличилась скорость выполнения и значительно уменьшилось выделение памяти.
Более быстрая проверка интерфейсов и использование их в преобразованиях типов. По данным Microsoft, производительность увеличилась на 16% – 38%.
Добавлены генераторы кода для API System.Text.Json , что опять же повысило производительность и уменьшило выделение памяти. Кроме того, JsonSerializer поддерживает IAsyncEnumerable :
Релиз .NET 6.0 также ознаменовался выходом новой версии языка C# — C# 10. Некоторые из его новвоведений:
Глобальные пространства имен. Достаточно подключить пространство имен в один файл кода с помощью директивы global using , и оно будет доступно во всех файлах проекта.
Пространства имен уровня файла. Так, вместо
Теперь можно создавать объекты record в виде структур (раньше все record представляли классы)
Также вместе с фреймворком вышла новая версия F# — F# 6
.NET 6.0 позволяет использовать Hot Reload для динамческой перезагрузки приложения при изменении кода
Это первая версия фреймворка, которая поддерживает архитектуру Apple Silicon (Arm64) и значительно усовершенствована для работы Windows Arm64.
Некоторые изменения затронули Windows Forms, в частности, возможность установки шрифта для приложения, минимизация кода и ряд других
Добавлен ряд новых API:
Новые API в System.Math , например, SinCos для одновременного вычисления синуса и косинуса и ряд других
API для сжатия для WebSocket
Поддержка прокси для Socks4, Socks4a и Socks5
В Microsoft.Extensions.Hosting добавлено ConfigureHostOptions API
В Microsoft.Extensions.DependencyInjection добавлено CreateAsyncScope API для использования сервисами IAsyncDisposable
В System.Linq методы Enumerable.ElementAt и Enumerable.Take имеют поддержку Index и Range
Также добавлены новые методы DistinctBy/UnionBy/IntersectBy/ExceptBy/MaxBy/MinBy
А в методах FirstOrDefault/LastOrDefault/SingleOrDefault теперь можно установить значение по умолчанию:
Очередь на основе приоритетов — PriorityQueue
Новые структуры для представления дат и времени: DateOnly и TimeOnly
Отмечается, что .NET 6 поддерживается в Visual Studio 2022 и Visual Studio 2022 for Mac. Однако НЕ поддерживается в Visual Studio 2019 и Visual Studio for Mac 8. Кроме того, .NET 6 поддерживается в Visual Studio Code с помощью расширения для C#.