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.

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 problemdotnet/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 structinitierar 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:

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:

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.

Se även