(articolo redatto da Gaetano De Pascale)
A novembre 2023 Microsoft ha rilasciato sia la versione 8 di .Net che la versione 12 del linguaggio C#.
In questo articolo vogliamo concentrarci sul linguaggio di programmazione illustrando le novità che sono state introdotte in questa nuova versione.
Indice dei contenuti
- Primary constructors (Visual Studio 2022 version 17.6 Preview 2.)
- Collection expressions (Visual Studio 2022 version 17.7 Preview 5.)
- Parameters: ref readonly (Visual Studio 2022 version 17.8 Preview 2.)
- Optional parameters in lambda expressions (Visual Studio 2022 version 17.5 Preview 2.)
- Alias any type (Visual Studio 2022 version 17.6 Preview 3.)
- Experimental attribute (Visual Studio 2022 version 17.7 Preview 3.)
- Interceptors (Visual Studio 2022 version 17.7 Preview 3.)
Primary constructors
I primary constructors (costruttori primari) sono una nuova sintassi che permette di creare costruttori in qualsiasi classe o struct, non solo nei record. I costruttori primari hanno i parametri tra parentesi dopo il nome della classe, e questi parametri sono in scope per tutta la classe.
I costruttori primari permettono di semplificare la dichiarazione e l’inizializzazione dei membri della classe.
Ecco un esempio:
I costruttori primari non generano automaticamente le proprietà pubbliche per i parametri, come invece fanno i record. Questo permette di avere un maggiore controllo sulla visibilità e sul comportamento dei membri della classe o dello struct. Se si vuole aggiungere un costruttore secondario, questo deve chiamare il costruttore primario usando la sintassi this(…). Se si aggiunge un costruttore primario a una classe, il compilatore non genera più un costruttore implicito senza parametri. In uno struct, il costruttore implicito senza parametri inizializza tutti i campi, inclusi i parametri del costruttore primario, al modello a 0 bit.
Collection expressions
Le collection expressions sono una nuova sintassi che permette di creare valori in modo più conciso e intuitivo. Le “espressioni di raccolta” usano le parentesi graffe {} o quadre [] precedute dal carattere # per creare rispettivamente oggetti simili a mappe o a liste. Una collection expression può contenere altre collections, usando ad esempio lo spread operator “…” .
Le Collection expression possono creare diversi tipi, come:
- Tipi di array, come int[]
- Tipi Span<T>e System.ReadOnlySpan<T>
- Tipi che supportano gli inizializzatori di raccolta, come Collections.Generic.List<T>
Ecco alcuni esempi:
Sono utili per creare collection in modo più semplice e leggibile, senza dover usare costruttori o metodi aggiuntivi, e sono, inoltre, compatibili con le funzionalità esistenti del linguaggio, come destructuring, template literal e le funzioni.
Parameters: ref readonly
I parametri ref readonly sono una nuova tipologia di function parameters che permette di dichiarare parametri ref che non possono essere modificati all’interno del metodo o della funzione. I parametri ref readonly consentono di passare per riferimento valori che sono immutabili o che si vuole mantenere immutabili, come i record, i record struct, i record class, i tipi di record e tuple, e i tipi readonly struct. I parametri ref readonly permettono di evitare copie inutili e di garantire la sicurezza dei dati.
Ecco un esempio:
I parametri ref readonly possono essere usati con i tipi di ritorno ref readonly, che permettono di restituire per riferimento valori che sono immutabili o che si vuole mantenere immutabili.
Ecco un esempio:
I parametri ref readonly e i tipi di ritorno ref readonly sono utili per migliorare le prestazioni e la sicurezza dei programmi che usano valori immutabili o che si vuole mantenere immutabili, evitando copie inutili e modifiche accidentali.
Optional parameters in lambda expressions
I parametri lambda predefiniti sono una nuova sintassi che permette di dichiarare parametri opzionali nelle espressioni lambda, come si può fare nei metodi e nelle funzioni locali. Consentono di specificare un valore predefinito per un parametro, che viene usato se il parametro non viene fornito al momento della chiamata, e quindi di semplificare la scrittura e la lettura delle espressioni lambda, evitando di dover creare più versioni della stessa espressione lambda per gestire diversi casi.
Ecco un esempio:
I parametri lambda predefiniti possono essere usati con le funzioni di ordine superiore, come i metodi di estensione LINQ, per creare espressioni lambda più concise e flessibili.
Ecco un esempio:
Alias any type
Gli alias per qualsiasi tipo sono una nuova sintassi che permette di creare un nome alternativo per qualsiasi tipo, non solo per i tipi generici, come si può fare con la parola chiave using. Gli alias per qualsiasi tipo consentono di semplificare la scrittura e la lettura dei tipi, evitando di dover ripetere nomi lunghi o complessi. Gli alias per qualsiasi tipo si creano usando la parola chiave alias, seguita dal nome dell’alias e dal tipo originale.
Ecco un esempio:
Gli alias per qualsiasi tipo sono utili per creare nomi più significativi e leggibili per i tipi, e per evitare conflitti di nomi tra tipi diversi ma con lo stesso nome. Gli alias per qualsiasi tipo sono validi solo nello scope in cui sono definiti, e non sono visibili all’esterno.
Experimental attribute
L’attributo Experimental è un nuovo attributo che permette di marcare come sperimentali i membri di una classe o di uno struct, come i metodi, le proprietà, i campi, etc.
L’attributo consente di indicare che i membri marcati sono soggetti a cambiamenti o rimozioni in futuro, e che il loro uso potrebbe comportare problemi di compatibilità o di sicurezza.
Quando viene utilizzato, ad esempio, un metodo sperimentale verrà visualizzato in compilazione un warning.
Ecco un esempio
Interceptors
Gli interceptors sono una nuova funzionalità che permette di modificare il comportamento di un membro di una classe o di uno struct; consentono di aggiungere del codice prima o dopo l’esecuzione del membro originale, o di sostituire completamente il membro originale con un’implementazione alternativa. Si creano usando la parola chiave intercept, seguita dal nome del membro da intercettare e dal codice da eseguire.
Ecco un esempio:
Possono risultare particolarmente utili per implementare funzionalità come il logging, la validazione, la cache, la sicurezza, la trasformazione dei dati, o più in generale quando si vogliono applicare comportamenti ad un membro di una classe senza modificarne il codice originale.
Conclusioni
Che ne pensi di questa panoramica sul linguaggio di programmazione C# 12? Le novità introdotte in questa nuova versione ti sembrano utili?
Se anche tu vuoi occuparti di importanti progetti di sviluppo software
dai un’occhiata alle nostre opportunità di lavoro e conosciamoci subito!


