Nyheter i C# 12
C# 12 innehåller följande nya funktioner. Du kan prova dessa funktioner med den senaste Visual Studio 2022 version eller .NET 8 SDK.
Primära konstruktorer – Introducerade i Visual Studio 2022 version 17.6 Förhandsversion 2.
Samlingsuttryck – Introducerades 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
parametrar – introducerades i Visual Studio 2022 version 17.8 Preview 2.Alias för alla typer – Introducerades i Visual Studio 2022 version 17.6 Förhandsversion 3.
Experimentellt attribut – introducerades i Visual Studio 2022 version 17.7 Förhandsversion 3.
Interceptors - Förhandsvisningsfunktion introducerades i Visual Studio 2022 version 17.7 förhandsvisning 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 sidan .NET-nedladdningar. Du kan också ladda ned Visual Studio 2022, som innehåller .NET 8 SDK.
Notera
Vi är intresserade av din feedback om dessa funktioner. Om du stöter på problem med någon av dessa nya funktioner, skapa ett nytt problem i dotnet/roslyn repository.
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 är tillgängliga inom hela klassens kropp. 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 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-recordklasser 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 om där man utforskar primära konstruktorer och i artikeln om instanskonstruktorer.
Samlingsuttryck
Samlingsuttryck introducerar en ny terse-syntax för att skapa gemensamma samlingsvärden. Det går att infoga andra samlingar i dessa värden med hjälp av ett spridningselement ..e
.
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];
Elementet spread, ..e
i ett samlingsuttryck lägger till alla element i uttrycket. Argumentet måste vara en samlingstyp. Följande exempel visar hur spridningselementet 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,
Spread-elementet utvärderar varje element i uppräkningsuttrycket. Varje element ingår i utdatasamlingen.
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åkets referensartikel eller i funktionsspecifikationen .
ref readonly
parametrar
C# har infört 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 att argumenten kommenteras.
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 bakåtkompatibilitetsändring för anropare, vilket det 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 i specifikationen för ref readonly-parametrar.
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 alias alla typer, 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 funktionsspecifikation. Ett exempel på en genomgång av omstrukturering finns i Omstrukturera koden med hjälp av alias av valfri typ på .NET-bloggen.
Infogade matriser
Inline-arrayer används av runtime-teamet och andra biblioteksskapare 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 som följande 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 inline-arrayer på samma sätt som du skulle göra med vanliga 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 med attributet Experimental
är experimentella. Du kan läsa mer i artikeln om Allmänna attribut som lästs av kompilatorneller funktionsspecifikationen.
Interceptrar
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 under kompilering. 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ällkodsgeneratorn ersätter anrop till en interceptbar metod med ett anrop till metoden interceptor.
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.