Novità di C# 12

C# 12 include le nuove funzionalità seguenti. È possibile provare queste funzionalità usando la versione più recente di Visual Studio 2022 o .NET 8 SDK.

C# 12 è supportato in .NET 8. Per altre informazioni, vedere controllo delle versioni del linguaggio C#.

È possibile scaricare la versione più recente di .NET 8 SDK dalla pagina di download di .NET. È anche possibile scaricare Visual Studio 2022, che include .NET 8 SDK.

Nota

Microsoft è interessato ai commenti e suggerimenti su queste funzionalità. Se si riscontrano problemi con una di queste nuove funzionalità, creare un nuovo problema nel repository dotnet/roslyn .

Costruttori primari

È ora possibile creare costruttori primari in qualsiasi class e struct. I costruttori primari non sono più limitati ai record tipi. I parametri del costruttore primario sono inclusi nell'ambito per l'intero corpo della classe. Per garantire che tutti i parametri del costruttore primario siano assegnati in modo definitivo, tutti i costruttori dichiarati in modo esplicito devono chiamare il costruttore primario usando this() la sintassi. L'aggiunta di un costruttore primario a un class impedisce al compilatore di dichiarare un costruttore implicito senza parametri. In un structoggetto il costruttore implicito senza parametri inizializza tutti i campi, inclusi i parametri del costruttore primario nel modello a 0 bit.

Il compilatore genera proprietà pubbliche per i parametri del costruttore primario solo in record tipi, record class o record struct tipi. Le classi e gli struct non registrati potrebbero non voler sempre questo comportamento per i parametri del costruttore primario.

Altre informazioni sui costruttori primari sono disponibili nell'esercitazione per l'esplorazione dei costruttori primari e nell'articolo sui costruttori di istanza.

Espressioni di raccolta

Le espressioni di raccolta introducono una nuova sintassi terse per creare valori di raccolta comuni. L'inlining di altre raccolte in questi valori è possibile usando un operatore ..spread .

È possibile creare diversi tipi simili a raccolte senza richiedere supporto BCL esterno. Questi tipi sono:

Negli esempi seguenti vengono illustrati gli usi delle espressioni di raccolta:

// 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];

L'operatore spread, .. in un'espressione di raccolta sostituisce il relativo argomento con gli elementi di tale raccolta. L'argomento deve essere un tipo di raccolta. Gli esempi seguenti illustrano il funzionamento dell'operatore spread:

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,

L'operando di un operatore spread è un'espressione che può essere enumerata. L'operatore spread valuta ogni elemento dell'espressione di enumerazione.

È possibile usare espressioni di raccolta in qualsiasi punto in cui è necessaria una raccolta di elementi. Possono specificare il valore iniziale per una raccolta o essere passati come argomenti ai metodi che accettano tipi di raccolta. Altre informazioni sulle espressioni di raccolta sono disponibili nell'articolo di riferimento sul linguaggio sulle espressioni di raccolta o sulla specifica delle funzionalità.

ref readonly Parametri

C# ha aggiunto in parametri come modo per passare riferimenti readonly. in i parametri consentono sia variabili che valori e possono essere usati senza alcuna annotazione sugli argomenti.

L'aggiunta di ref readonly parametri consente maggiore chiarezza per le API che potrebbero usare ref parametri o in parametri:

Per altre informazioni sui ref readonly parametri, vedere l'articolo sui modificatori di parametri nella guida di riferimento al linguaggio o la specifica della funzionalità dei parametri ref readonly.

Parametri lambda predefiniti

È ora possibile definire i valori predefiniti per i parametri nelle espressioni lambda. La sintassi e le regole corrispondono all'aggiunta di valori predefiniti per gli argomenti a qualsiasi metodo o funzione locale.

Per altre informazioni sui parametri predefiniti sulle espressioni lambda, vedere l'articolo sulle espressioni lambda.

Alias qualsiasi tipo

È possibile usare la direttiva alias per eseguire l'alias using di qualsiasi tipo, non solo per i tipi denominati. Ciò significa che è possibile creare alias semantici per tipi di tupla, tipi di matrice, tipi di puntatore o altri tipi non sicuri. Per altre informazioni, vedere la specifica della funzionalità.

Matrici inline

Le matrici inline vengono usate dal team di runtime e da altri autori di librerie per migliorare le prestazioni nelle app. Le matrici inline consentono a uno sviluppatore di creare una matrice di dimensioni fisse in un struct tipo. Uno struct con un buffer inline deve fornire caratteristiche di prestazioni simili a un buffer di dimensioni fisse non sicure. È probabile che non dichiari le tue matrici inline, ma le usi in modo trasparente quando vengono esposte come System.Span<T> o System.ReadOnlySpan<T> oggetti dalle API di runtime.

Una matrice inline è dichiarata simile alla seguente struct:

[System.Runtime.CompilerServices.InlineArray(10)]
public struct Buffer
{
    private int _element0;
}

Le si usano come qualsiasi altra matrice:

var buffer = new Buffer();
for (int i = 0; i < 10; i++)
{
    buffer[i] = i;
}

foreach (var i in buffer)
{
    Console.WriteLine(i);
}

La differenza è che il compilatore può sfruttare informazioni note su una matrice inline. È probabile che si usano matrici inline come qualsiasi altra matrice. Per altre informazioni su come dichiarare matrici inline, vedere le informazioni di riferimento sul linguaggio sui struct tipi.

Attributo sperimentale

I tipi, i metodi o gli assembly possono essere contrassegnati con per System.Diagnostics.CodeAnalysis.ExperimentalAttribute indicare una funzionalità sperimentale. Il compilatore genera un avviso se si accede a un metodo o a un tipo annotato con il ExperimentalAttribute. Tutti i tipi inclusi in un assembly contrassegnato con l'attributo Experimental sono sperimentali. Per altre informazioni, vedere l'articolo sugli attributi generali letti dal compilatore o la specifica della funzionalità.

Intercettori

Avviso

Gli intercettori sono una funzionalità sperimentale, disponibile in modalità di anteprima con C# 12. La funzionalità può essere soggetta a modifiche di rilievo o rimozione in una versione futura. Non sono quindi consigliabili per le applicazioni di produzione o rilasciate.

Per usare gli intercettori, il progetto utente deve specificare la proprietà <InterceptorsPreviewNamespaces>. Si tratta di un elenco di spazi dei nomi che possono contenere intercettori.

Ad esempio: <InterceptorsPreviewNamespaces>$(InterceptorsPreviewNamespaces);Microsoft.AspNetCore.Http.Generated;MyLibrary.Generated</InterceptorsPreviewNamespaces>

Un intercettore è un metodo che può sostituire in modo dichiarativo una chiamata a un metodo intercettabile con una chiamata a se stessa in fase di compilazione. Questa sostituzione avviene con l'intercettore che dichiara le posizioni di origine delle chiamate intercettate. Gli intercettori offrono una funzionalità limitata per modificare la semantica del codice esistente aggiungendo nuovo codice a una compilazione, ad esempio in un generatore di origine.

Si usa un intercettore come parte di un generatore di origine per modificare, anziché aggiungere codice a una compilazione di origine esistente. Il generatore di origine sostituisce le chiamate a un metodo intercettabile con una chiamata al metodo intercettore .

Se si è interessati a sperimentare con gli intercettori, è possibile ottenere altre informazioni leggendo la specifica della funzionalità. Se si usa la funzionalità, assicurarsi di rimanere aggiornati con le modifiche apportate alla specifica della funzionalità per questa funzionalità sperimentale. Se la funzionalità è stata finalizzata, verranno aggiunte altre indicazioni in questo sito.

Vedi anche