Новые возможности C# 13
C# 13 включает следующие новые функции. Эти функции можно попробовать с помощью последней версии Visual Studio 2022 или пакета SDK для .NET 9:
- коллекции
params
-
новые
lock
типа и семантики. -
новая последовательность выхода —
\e
. - улучшения натурального типа группы методов
- неявное обращение к индексатору в инициализации объектов
-
Включить
ref
локальные иunsafe
контексты в итераторах и асинхронных методах -
Включить типы
ref struct
для реализации интерфейсов. - Разрешить типы структур ссылок в качестве аргументов для параметров типа в универсальных шаблонах.
-
Частичные свойства и индексаторы теперь разрешены в
partial
типах. - приоритет разрешения перегрузки позволяет авторам библиотек определить одну перегрузку как предпочтительную по сравнению с другими.
Начиная с Visual Studio 17.12, C# 13 включает контекстное ключевое слово field
в качестве функции предварительного просмотра.
C# 13 поддерживается в .NET 9. Дополнительные сведения см. в версии языка C# .
Вы можете скачать последний пакет SDK для .NET 9 на странице загрузки .NET . Вы также можете скачать Visual Studio 2022, которая включает пакет SDK для .NET 9.
Новые функции добавляются на страницу "Новые возможности В C#", когда они доступны в общедоступных предварительных версиях. Раздел рабочего набора на странице статуса функций Roslyn отслеживает, когда предстоящие функции объединяются в основную ветвь.
Критические изменения, внесенные в C# 13, можно найти в нашей статье о критических изменениях.
Заметка
Мы заинтересованы в ваших отзывах об этих функциях. Если вы найдете проблемы с любым из этих новых функций, создайте новую проблему в репозитории dotnet/roslyn.
коллекции params
Модификатор params
не ограничивается типами массивов. Теперь можно использовать params
с любым распознаваемым типом коллекции, включая System.Span<T>, System.ReadOnlySpan<T>и типы, реализующие System.Collections.Generic.IEnumerable<T> и имеющие метод Add
. Помимо конкретных типов, интерфейсы System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.Generic.IReadOnlyList<T>, System.Collections.Generic.ICollection<T>и System.Collections.Generic.IList<T> также можно использовать.
При использовании типа интерфейса компилятор синтезирует хранилище для предоставленных аргументов. Дополнительные сведения см. в спецификации функций для коллекций params
.
Например, объявления методов могут объявлять диапазоны как параметры params
:
public void Concat<T>(params ReadOnlySpan<T> items)
{
for (int i = 0; i < items.Length; i++)
{
Console.Write(items[i]);
Console.Write(" ");
}
Console.WriteLine();
}
Новый объект блокировки
Среда выполнения .NET 9 включает новый тип для синхронизации потоков, тип System.Threading.Lock. Этот тип обеспечивает лучшую синхронизацию потоков через свой API. Метод Lock.EnterScope() входит в эксклюзивную область.
ref struct
, возвращенный из него, поддерживает шаблон Dispose()
для выхода из эксклюзивной области.
Оператор C# lock
распознает, является ли объект блокировки целевым объектом Lock
. Если да, используется обновленный API вместо традиционного API, использующего System.Threading.Monitor. Компилятор также распознает, если преобразовать объект Lock
в другой тип, а код на основе Monitor
будет создан. Дополнительные сведения см. в спецификации функций для нового объекта блокировки .
Эта функция позволяет вам воспользоваться преимуществами нового типа библиотеки, изменив тип объекта lock
, который вы используете. Никакого другого кода не требуется изменять.
Новая escape-последовательность
Вы можете использовать \e
в качестве символьного литерала последовательности экранирования для ESCAPE
символа Юникод U+001B
. Ранее вы использовали \u001b
или \x1b
. Использование \x1b
не рекомендуется, поскольку если следующие символы после 1b
являются допустимыми шестнадцатеричными цифрами, они становятся частью escape-последовательности.
Естественный тип группы методов
Эта функция делает небольшие оптимизации для разрешения перегрузки с участием групп методов. Группа методов — это совокупность метода и всех его перегрузок с одинаковым именем. Предыдущее поведение компилятора состояло в создании полного набора кандидатных методов для группы методов. Если требовался естественный тип, его определяли из полного набора кандидатных методов.
Новое поведение заключается в том, чтобы сужать набор кандидатных методов в рамках каждой области, удаляя те из них, которые не применимы. Как правило, удаленные методы — это универсальные методы с неправильной арностью или с ограничениями, которые не удовлетворены. Процесс продолжается до следующей внешней области, только если методы-кандидаты не найдены. Этот процесс более тесно соответствует общему алгоритму разрешения перегрузки. Если все кандидатные методы, найденные в заданной области, не соответствуют критериям, кандидатная группа методов не имеет естественного типа.
Подробные сведения об изменениях в спецификации предложения можно прочитать.
Неявный доступ к индексу
Неявный оператор индекса "с конца" ^
теперь допускается в выражении инициализатора объектов. Например, теперь можно инициализировать массив в инициализаторе объектов, как показано в следующем коде:
public class TimerRemaining
{
public int[] buffer { get; set; } = new int[10];
}
var countdown = new TimerRemaining()
{
buffer =
{
[^1] = 0,
[^2] = 1,
[^3] = 2,
[^4] = 3,
[^5] = 4,
[^6] = 5,
[^7] = 6,
[^8] = 7,
[^9] = 8,
[^10] = 9
}
};
Класс TimerRemaining
включает массив buffer
, инициализированный до длины 10. В приведенном выше примере значения присваиваются этому массиву с помощью оператора индекса "с конца" (^
), что в результате создаёт массив, который отсчитывается от 9 до 0.
В версиях до C# 13 оператор ^
нельзя использовать в инициализаторе объектов. Необходимо индексировать элементы с начала.
ref
и unsafe
в итераторах и async
методах
Эта функция и следующие две функции позволяют ref struct
типам использовать новые конструкции. Вы не будете их использовать, если только вы не создадите собственные ref struct
типы. Скорее всего, вы увидите косвенные преимущества по мере того, как System.Span<T> и System.ReadOnlySpan<T> будут получать больше функциональности.
До C# 13 методы итератора (методы, использующие yield return
) и методы async
не могли объявлять локальные ref
переменные, а также не могли бы иметь контекст unsafe
.
В C# 13 методы async
могут объявлять ref
локальные переменные или локальные переменные типа ref struct
. Однако эти переменные нельзя получить через await
границу. Они не могут быть доступны через границу yield return
.
Это ослабленное ограничение позволяет компилятору разрешить безопасное использование ref
локальных переменных и ref struct
типов в большем числе мест. В этих методах можно безопасно использовать такие типы, как System.ReadOnlySpan<T>. Компилятор сообщает вам, если вы нарушаете правила безопасности.
Таким же образом C# 13 позволяет использовать контексты unsafe
в методах итераторов. Однако все операторы yield return
и yield break
должны находиться в безопасных контекстах.
allows ref struct
До C# 13 ref struct
типы не могут быть объявлены в качестве аргумента типа для универсального типа или метода. Теперь объявления универсальных типов могут добавлять анти-ограничение, allows ref struct
. Это анти-ограничение объявляет, что аргумент типа, предоставленный для этого параметра типа, может быть типом ref struct
. Компилятор применяет правила ссылочной безопасности ко всем экземплярам этого параметра типа.
Например, можно объявить универсальный тип, например следующий код:
public class C<T> where T : allows ref struct
{
// Use T as a ref struct:
public void M(scoped T p)
{
// The parameter p must follow ref safety rules
}
}
Это позволяет использовать такие типы, как System.Span<T> и System.ReadOnlySpan<T> с универсальными алгоритмами, где это применимо. Вы можете узнать больше в обновлениях для where
и в статье руководства по программированию об универсальных ограничениях .
ref struct
интерфейсы
До C# 13 ref struct
типы не были разрешены для реализации интерфейсов. Начиная с C# 13, они могут. Можно объявить, что тип ref struct
реализует интерфейс. Однако для обеспечения соответствия правилам безопасности не удается преобразовать тип ref struct
в тип интерфейса. Это преобразование является преобразованием бокса и может нарушить безопасность ссылок. Явные объявления методов интерфейса в ref struct
можно получить только через параметр типа, где этот параметр типа allows ref struct
. Кроме того, ref struct
типы должны реализовать все методы, объявленные в интерфейсе, включая те, которые имеют реализацию по умолчанию.
Узнайте больше об обновлениях для типов иref struct
, а также о добавлении универсального ограничения allows ref struct
для типа.
Частично задействованные члены
Вы можете объявить свойства partial
и индексаторы partial
в C# 13. Частичные свойства и индексаторы обычно следуют тем же правилам, что и методы partial
: создается один объявление объявления и один реализации объявления. Подписи двух объявлений должны совпадать. Одно из ограничений заключается в том, что нельзя использовать объявление автоматического свойства для реализации частичного свойства . Свойства, которые не объявляют тело, считаются объявлением.
public partial class C
{
// Declaring declaration
public partial string Name { get; set; }
}
public partial class C
{
// implementation declaration:
private string _name;
public partial string Name
{
get => _name;
set => _name = value;
}
}
Дополнительные сведения см. в статье о частичных членах .
Приоритет разрешения перегрузки
В C# 13 компилятор распознает OverloadResolutionPriorityAttribute, чтобы отдавать предпочтение одной перегрузке над другой. Авторы библиотеки могут использовать этот атрибут, чтобы гарантировать, что новая, более эффективная перегрузка предпочтительна по сравнению с существующей перегрузкой. Например, можно добавить новую перегрузку, которая более эффективна. Вы не хотите прерывать существующий код, использующий библиотеку, но вы хотите, чтобы пользователи обновляли новую версию при повторной компиляции. Приоритет разрешения перегрузки можно использовать для информирования компилятора о том, какая перегрузка должна быть предпочтительна. Перегрузки с наивысшим приоритетом предпочтительнее.
Эта функция предназначена для авторов библиотек, чтобы избежать неоднозначности при добавлении новых перегрузок. Авторы библиотеки должны проявлять осторожность с этим атрибутом, чтобы избежать путаницы.
Ключевое слово field
Контекстное ключевое слово field
представлено в C# 13 в качестве предварительной функции. Маркер field
обращается к синтезированному полю резервного копирования компилятора в методе доступа к свойствам. Он позволяет создавать текст метода доступа без объявления явного поля резервного копирования в объявлении типа. Вы можете определить тело для одного или обоих акцессоров свойства, связанного с полем.
Функция field
выпущена как предварительная версия функции. Мы хотим узнать о своем опыте использования. Существует потенциальное изменение, приводящее к сбоям, или путаница при чтении кода в типах, которые также включают поле с именем field
. Вы можете использовать @field
или this.field
для диамбигуации между ключевым словом field
и идентификатором.
Важный
Ключевое слово field
— это предварительная версия функции в C# 13. Для использования контекстного ключевого слова field
, необходимо использовать .NET 9 и задать элемент <LangVersion>
на preview
в вашем файле проекта.
Следует тщательно использовать функцию ключевого слова field
в классе с полем с именем field
. Новое ключевое слово field
затмевает поле с именем field
в аксессоре свойства. Можно изменить имя переменной field
или использовать маркер @
для ссылки на идентификатор field
как @field
. Вы можете узнать больше, прочитав спецификацию характеристики для ключевого слова field
.
Если вы попробуете эту функцию и у вас будет отзыв, добавьте его в проблему в репозитории csharplang
.