Новые возможности C# 12
C# 12 включает следующие новые функции. Эти функции можно попробовать с помощью последней версии Visual Studio 2022 или пакета SDK для .NET 8.
Основные конструкторы — представлены в Visual Studio 2022 версии 17.6( предварительная версия 2).
Выражения коллекции . Представлено в Visual Studio 2022 версии 17.7( предварительная версия 5).
Встроенные массивы — представлены в Visual Studio 2022 версии 17.7( предварительная версия 3).
Необязательные параметры в лямбда-выражениях . Представлено в Visual Studio 2022 версии 17.5 ( предварительная версия 2).
ref readonly
параметры — представлено в Visual Studio 2022 версии 17.8( предварительная версия 2).Псевдоним любого типа — представлен в Visual Studio 2022 версии 17.6( предварительная версия 3).
Экспериментальный атрибут — представлен в Visual Studio 2022 версии 17.7( предварительная версия 3).
Функция предварительной версии перехватчиков - , представленная в Visual Studio 2022 версии 17.7( предварительная версия 3).
C# 12 поддерживается в .NET 8. Дополнительные сведения см. в статье Управление версиями языка C#.
Скачать последний пакет SDK для .NET 8 можно на странице загрузки .NET. Вы также можете скачать Visual Studio 2022, который включает пакет SDK для .NET 8.
Примечание.
Мы заинтересованы в ваших отзывах об этих функциях. Если вы найдете проблемы с любым из этих новых функций, создайте новую проблему в репозитории dotnet/roslyn .
Основные конструкторы
Теперь вы можете создавать первичные конструкторы в любом class
и struct
. Основные конструкторы больше не ограничиваются типами record
. Основные параметры конструктора находятся в область для всего текста класса. Чтобы убедиться, что все параметры первичного конструктора определенно назначены, все явно объявленные конструкторы должны вызывать основной конструктор с помощью this()
синтаксиса. Добавление первичного конструктора в class
объект запрещает компилятору объявлять неявный конструктор без параметров. struct
В неявном конструкторе без параметров инициализирует все поля, включая параметры первичного конструктора в 0-битовый шаблон.
Компилятор создает общедоступные свойства для параметров первичного конструктора только в record
типах или record class
record struct
типах. Некорректные классы и структуры могут не всегда использовать это поведение для параметров первичного конструктора.
Дополнительные сведения о первичных конструкторах см. в руководстве по изучению основных конструкторов и в статье по конструкторам экземпляров.
Выражения коллекции
Выражения коллекции представляют новый синтаксис terse для создания общих значений коллекции. Встраивание других коллекций в эти значения возможно с помощью оператора ..
распространения.
Можно создать несколько типов, таких как коллекция, без поддержки внешнего BCL. Это следующие типы:
- Типы массивов, такие как
int[]
. - System.Span<T> и System.ReadOnlySpan<T>.
- Типы, поддерживающие инициализаторы коллекций, например System.Collections.Generic.List<T>.
В следующих примерах показано использование выражений коллекции:
// Create an array:
int[] a = [1, 2, 3, 4, 5, 6, 7, 8];
// Create a list:
List<string> b = ["one", "two", "three"];
// Create a span
Span<char> c = ['a', 'b', 'c', 'd', 'e', 'f', 'h', 'i'];
// Create a jagged 2D array:
int[][] twoD = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
// Create a jagged 2D array from variables:
int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
int[] row2 = [7, 8, 9];
int[][] twoDFromVariables = [row0, row1, row2];
Оператор распространения..
в выражении коллекции заменяет его аргумент элементами из этой коллекции. Аргумент должен быть типом коллекции. В следующих примерах показано, как работает оператор распространения:
int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
int[] row2 = [7, 8, 9];
int[] single = [.. row0, .. row1, .. row2];
foreach (var element in single)
{
Console.Write($"{element}, ");
}
// output:
// 1, 2, 3, 4, 5, 6, 7, 8, 9,
Операнды оператора распространения — это выражение, которое можно перечислить. Оператор распространения вычисляет каждый элемент выражения перечислений.
Выражения коллекции можно использовать в любом месте, где требуется коллекция элементов. Они могут указать начальное значение для коллекции или передаваться в качестве аргументов методам, которые принимают типы коллекций. Дополнительные сведения о выражениях коллекции см. в справочной статье о выражениях коллекции или спецификации компонентов.
параметры ref readonly
C# добавил in
параметры в качестве способа передачи ссылок на чтение. in
параметры позволяют использовать переменные и значения без каких-либо заметок в аргументах.
ref readonly
Добавление параметров обеспечивает более четкость для API, которые могут использовать ref
параметры или in
параметры:
- Интерфейсы API, созданные ранее,
in
могут использоватьref
, даже если аргумент не изменен. Эти API можно обновить с помощьюref readonly
. Это не будет критическим изменением для вызывающих абонентов, как было бы, еслиref
параметр был измененin
на . Например, System.Runtime.InteropServices.Marshal.QueryInterface. - API, которые принимают
in
параметр, но логически требуют переменной. Выражение значения не работает. Например, System.ReadOnlySpan<T>.ReadOnlySpan<T>(T). - API, которые используются
ref
, так как им требуется переменная, но не мутируют эти переменные. Например, System.Runtime.CompilerServices.Unsafe.IsNullRef.
Дополнительные сведения о параметрах см. в статье о ref readonly
модификаторах параметров в справочнике по языку или спецификации функции refonly параметров .
Параметры лямбда-кода по умолчанию
Теперь можно определить значения по умолчанию для параметров в лямбда-выражениях. Синтаксис и правила совпадают с добавлением значений по умолчанию для аргументов в любой метод или локальную функцию.
Дополнительные сведения о параметрах по умолчанию для лямбда-выражений см. в статье об лямбда-выражениях.
Псевдоним любого типа
Директиву using
псевдонима можно использовать для псевдонимов любого типа, а не только именованных типов. Это означает, что можно создавать семантические псевдонимы для типов кортежей, типов массивов, типов указателей или других небезопасных типов. Дополнительные сведения см. в спецификации компонентов.
Встроенные массивы
Встроенные массивы используются командой среды выполнения и другими авторами библиотек для повышения производительности в приложениях. Встроенные массивы позволяют разработчику создавать массив фиксированного размера в типе struct
. Структуру с встроенным буфером следует обеспечить характеристики производительности, аналогичные небезопасной буферу фиксированного размера. Скорее всего, вы не объявите собственные встроенные массивы, но вы используете их прозрачно, когда они предоставляются как System.Span<T> или System.ReadOnlySpan<T> объекты из API среды выполнения.
Встроенный массив объявлен следующим образом struct
:
[System.Runtime.CompilerServices.InlineArray(10)]
public struct Buffer
{
private int _element0;
}
Они используются как любой другой массив:
var buffer = new Buffer();
for (int i = 0; i < 10; i++)
{
buffer[i] = i;
}
foreach (var i in buffer)
{
Console.WriteLine(i);
}
Разница заключается в том, что компилятор может воспользоваться известными сведениями о встроенном массиве. Скорее всего, вы используете встроенные массивы, как и любой другой массив. Дополнительные сведения о том, как объявлять встроенные массивы, см. в справочнике по языку по struct
типам.
Экспериментальный атрибут
Типы, методы или сборки можно помечать с System.Diagnostics.CodeAnalysis.ExperimentalAttribute помощью элемента, указывающего экспериментальную функцию. Компилятор выдает предупреждение при доступе к методу или типу, аннотированному ExperimentalAttributeс помощью . Все типы, включенные в сборку, помеченную атрибутом Experimental
, являются экспериментальными. Дополнительные сведения см. в статье об общих атрибутах компилятора или спецификации компонентов.
Перехватчики
Предупреждение
Перехватчики — это экспериментальная функция, доступная в режиме предварительной версии с C# 12. Эта функция может быть подвержена критическим изменениям или удалению в будущем выпуске. Поэтому не рекомендуется для рабочих или выпущенных приложений.
Чтобы использовать перехватчики, проект пользователя должен указать свойство <InterceptorsPreviewNamespaces>
. Это список пространств имен, которые могут содержать перехватчики.
Например: <InterceptorsPreviewNamespaces>$(InterceptorsPreviewNamespaces);Microsoft.AspNetCore.Http.Generated;MyLibrary.Generated</InterceptorsPreviewNamespaces>
Перехватчик — это метод, который может декларативно заменить вызов перехватываемого метода вызовом к себе во время компиляции. Эта подстановка происходит путем объявления перехватчиком исходных расположений вызовов, которые он перехватывает. Перехватчики предоставляют ограниченное средство для изменения семантики существующего кода путем добавления нового кода в компиляцию, например в генератор источника.
Перехватчик используется как часть генератора источника для изменения, а не добавления кода в существующую исходную компиляцию. Генератор источника заменяет вызовы перехватываемого метода вызовом метода перехватчика .
Если вы заинтересованы в эксперименте с перехватчиками, вы можете узнать больше, прочитав спецификацию функции. Если вы используете эту функцию, не забудьте оставаться в курсе всех изменений в спецификации компонентов для этой экспериментальной функции. Если эта функция завершена, мы добавим дополнительные рекомендации на этом сайте.