Nyheter i C# 12
C# 12 innehåller följande nya funktioner. Du kan prova de här funktionerna med den senaste Visual Studio 2022-versionen eller .NET 8 SDK.
Primära konstruktorer – Introducerade i Visual Studio 2022 version 17.6 Förhandsversion 2.
Samlingsuttryck – Introducerade i Visual Studio 2022 version 17.7 Förhandsversion 5.
Infogade matriser – Introducerade i Visual Studio 2022 version 17.7 Förhandsversion 3.
Valfria parametrar i lambda-uttryck – Introducerades i Visual Studio 2022 version 17.5 Förhandsversion 2.
ref readonly
parameters – introducerades i Visual Studio 2022 version 17.8 Preview 2.Alias alla typer – introduceras i Visual Studio 2022 version 17.6 Förhandsversion 3.
Experimentellt attribut – introducerades i Visual Studio 2022 version 17.7 Preview 3.
Förhandsgranskningsfunktionen Interceptors - introducerades i Visual Studio 2022 version 17.7 Förhandsversion 3.
C# 12 stöds på .NET 8. Mer information finns i C#-språkversioner.
Du kan ladda ned den senaste .NET 8 SDK från nedladdningssidan för .NET. Du kan också ladda ned Visual Studio 2022, som innehåller .NET 8 SDK.
Kommentar
Vi är intresserade av din feedback om dessa funktioner. Om du får problem med någon av dessa nya funktioner skapar du ett nytt problem på dotnet/roslyn-lagringsplatsen .
Primära konstruktorer
Nu kan du skapa primära konstruktorer i valfri class
och struct
. Primära konstruktorer är inte längre begränsade till record
typer. Primära konstruktorparametrar finns i omfånget för hela klassens brödtext. För att säkerställa att alla primära konstruktorparametrar definitivt tilldelas måste alla explicit deklarerade konstruktorer anropa den primära konstruktorn med hjälp av this()
syntax. Om du lägger till en primär konstruktor i en class
hindrar du kompilatorn från att deklarera en implicit parameterlös konstruktor. I en struct
initierar den implicita parameterlösa konstruktorn alla fält, inklusive primära konstruktorparametrar till 0-bitarsmönstret.
Kompilatorn genererar offentliga egenskaper för primära konstruktorparametrar endast i record
typer, antingen record class
eller record struct
typer. Icke-inspelade klasser och structs kanske inte alltid vill ha det här beteendet för primära konstruktorparametrar.
Du kan lära dig mer om primära konstruktorer i självstudien för att utforska primära konstruktorer och i artikeln om instanskonstruktorer.
Samlingsuttryck
Samlingsuttryck introducerar en ny terse-syntax för att skapa gemensamma samlingsvärden. Det är möjligt att ange andra samlingar i dessa värden med hjälp av en spridningsoperator ..
.
Flera samlingsliknande typer kan skapas utan att det krävs externT BCL-stöd. Följande typer är:
- Matristyper, till exempel
int[]
. - System.Span<T> och System.ReadOnlySpan<T>.
- Typer som stöder insamlingsinitierare, till exempel System.Collections.Generic.List<T>.
I följande exempel visas användning av samlingsuttryck:
// 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];
Spridningsoperatorn ..
ersätter i ett samlingsuttryck sitt argument med elementen från samlingen. Argumentet måste vara en samlingstyp. Följande exempel visar hur spridningsoperatorn fungerar:
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,
Operand för en spridningsoperator är ett uttryck som kan räknas upp. Spridningsoperatorn utvärderar varje element i uppräkningsuttrycket.
Du kan använda samlingsuttryck var du än behöver en samling element. De kan ange det ursprungliga värdet för en samling eller skickas som argument till metoder som använder samlingstyper. Du kan lära dig mer om samlingsuttryck i språkreferensartikeln om samlingsuttryck eller funktionsspecifikationen.
ref readonly
Parametrar
C# lade till in
parametrar som ett sätt att skicka skrivskyddade referenser. in
parametrar tillåter både variabler och värden och kan användas utan någon anteckning om argument.
Tillägget av ref readonly
parametrar ger mer klarhet för API:er som kan använda ref
parametrar eller in
parametrar:
- API:er som skapades innan
in
introducerades kan användaref
även om argumentet inte har ändrats. Dessa API:er kan uppdateras medref readonly
. Det blir ingen icke-bakåtkompatibel ändring för anropare, vilket skulle vara om parameternref
ändrades tillin
. Ett exempel är System.Runtime.InteropServices.Marshal.QueryInterface. - API:er som tar en
in
parameter, men som logiskt kräver en variabel. Ett värdeuttryck fungerar inte. Ett exempel är System.ReadOnlySpan<T>.ReadOnlySpan<T>(T). - API:er som använder
ref
eftersom de kräver en variabel, men som inte muterar variabeln. Ett exempel är System.Runtime.CompilerServices.Unsafe.IsNullRef.
Mer information om ref readonly
parametrar finns i artikeln om parametermodifierare i språkreferensen eller referensparametrarnas funktionsspecifikation.
Standardparametrar för lambda
Nu kan du definiera standardvärden för parametrar för lambda-uttryck. Syntaxen och reglerna är samma som att lägga till standardvärden för argument till valfri metod eller lokal funktion.
Du kan lära dig mer om standardparametrar för lambda-uttryck i artikeln om lambda-uttryck.
Alias för valfri typ
Du kan använda using
aliasdirektivet för att aliasa vilken typ som helst, inte bara namngivna typer. Det innebär att du kan skapa semantiska alias för tuppelns typer, matristyper, pekartyper eller andra osäkra typer. Mer information finns i funktionsspecifikationen.
Infogade matriser
Infogade matriser används av körningsteamet och andra biblioteksförfattare för att förbättra prestanda i dina appar. Med infogade matriser kan en utvecklare skapa en matris med fast storlek i en struct
typ. En struct med en infogad buffert bör ge prestandaegenskaper som liknar en osäker buffert med fast storlek. Du deklarerar förmodligen inte egna infogade matriser, men du använder dem transparent när de exponeras som System.Span<T> eller System.ReadOnlySpan<T> objekt från körnings-API:er.
En infogad matris deklareras ungefär så här struct
:
[System.Runtime.CompilerServices.InlineArray(10)]
public struct Buffer
{
private int _element0;
}
Du använder dem som alla andra matriser:
var buffer = new Buffer();
for (int i = 0; i < 10; i++)
{
buffer[i] = i;
}
foreach (var i in buffer)
{
Console.WriteLine(i);
}
Skillnaden är att kompilatorn kan dra nytta av känd information om en infogad matris. Du använder förmodligen infogade matriser på samma sätt som andra matriser. Mer information om hur du deklarerar infogade matriser finns i språkreferensen för struct
typer.
Experimentellt attribut
Typer, metoder eller sammansättningar kan markeras med System.Diagnostics.CodeAnalysis.ExperimentalAttribute för att indikera en experimentell funktion. Kompilatorn utfärdar en varning om du kommer åt en metod eller skriver kommenterad med ExperimentalAttribute. Alla typer som ingår i en sammansättning som har markerats Experimental
med attributet är experimentella. Du kan läsa mer i artikeln om allmänna attribut som lästs av kompilatorn eller funktionsspecifikationen.
Interceptorer
Varning
Interceptorer är en experimentell funktion som är tillgänglig i förhandsgranskningsläge med C# 12. Funktionen kan bli föremål för icke-bakåtkompatibla ändringar eller borttagning i en framtida version. Därför rekommenderas det inte för produktion eller utgivna program.
För att kunna använda interceptorer måste användarprojektet ange egenskapen <InterceptorsPreviewNamespaces>
. Det här är en lista över namnområden som tillåts innehålla interceptorer.
Till exempel: <InterceptorsPreviewNamespaces>$(InterceptorsPreviewNamespaces);Microsoft.AspNetCore.Http.Generated;MyLibrary.Generated</InterceptorsPreviewNamespaces>
En interceptor är en metod som deklarativt kan ersätta ett anrop till en skärningsbar metod med ett anrop till sig själv vid kompileringstillfället. Den här ersättningen sker genom att interceptorn deklarerar källplatserna för de anrop som den fångar upp. Interceptorer ger en begränsad möjlighet att ändra semantiken för befintlig kod genom att lägga till ny kod i en kompilering, till exempel i en källgenerator.
Du använder en interceptor som en del av en källgenerator för att ändra i stället för att lägga till kod i en befintlig källkompilering. Källgeneratorn ersätter anrop till en skärningsbar metod med ett anrop till interceptor-metoden .
Om du är intresserad av att experimentera med interceptorer kan du lära dig mer genom att läsa funktionsspecifikationen. Om du använder funktionen ser du till att hålla dig uppdaterad med eventuella ändringar i funktionsspecifikationen för den här experimentella funktionen. Om funktionen har slutförts lägger vi till mer vägledning på den här webbplatsen.