Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
C# 14 include le nuove funzionalità seguenti. È possibile provare queste funzionalità usando la versione più recente di Visual Studio 2022 o .NET 10 SDK:
- Membri dell'estensione
- Assegnazione condizionale Null
-
nameof
supporta tipi generici non associati -
Conversioni più implicite per
Span<T>
eReadOnlySpan<T>
- Modificatori su parametri lambda semplici
-
field
proprietà garantite -
partial
eventi e costruttori - Operatori di assegnazione composti definiti dall'utente
C# 14 è supportato in .NET 10. Per ulteriori informazioni, vedere versionamento del linguaggio C#.
È possibile scaricare la versione più recente di .NET 10 SDK dalla pagina di download di .NET. È anche possibile scaricare Visual Studio 2022, che include .NET 10 SDK.
Le nuove funzionalità vengono aggiunte alla pagina "Novità in C#" quando sono disponibili nelle versioni di anteprima pubblica. La sezione working set della pagina di stato della funzionalità roslyn tiene traccia quando le funzionalità future vengono unite nel ramo principale. Questo articolo è stato aggiornato per .NET 10 Preview 1.
È possibile trovare eventuali modifiche di rilievo introdotte in C# 14 nell'articolo sulle modifiche di rilievo.
Annotazioni
Microsoft è interessato ai commenti e suggerimenti su queste funzionalità. Se trovi questioni con una di queste nuove funzionalità, crea un nuovo problema nel repository dotnet/roslyn.
Membri dell'estensione
C# 14 aggiunge una nuova sintassi per definire i membri dell'estensione. La nuova sintassi consente di dichiarare proprietà di estensione oltre ai metodi di estensione. È anche possibile dichiarare membri di estensione che estendono il tipo, anziché un'istanza del tipo. In altre parole, questi nuovi membri di estensione possono essere visualizzati come membri statici del tipo che estendi. L'esempio di codice seguente illustra un esempio dei diversi tipi di membri di estensione che è possibile dichiarare:
public static class Enumerable
{
// Extension block
extension<TSource>(IEnumerable<TSource> source) // extension members for IEnumerable<TSource>
{
// Extension property:
public bool IsEmpty => !source.Any();
// Extension indexer:
public TSource this[int index] => source.Skip(index).First();
// Extension method:
public IEnumerable<TSource> Where(Func<TSource, bool> predicate) { ... }
}
// extension block, with a receiver type only
extension<TSource>(IEnumerable<TSource>) // static extension members for IEnumerable<Source>
{
// static extension method:
public static IEnumerable<TSource> Combine(IEnumerable<TSource> first, IEnumerable<TSource> second) { ... }
// static extension property:
public static IEnumerable<TSource> Identity => Enumerable.Empty<TSource>();
}
}
I membri nel primo blocco di estensione vengono chiamati come se fossero membri dell'istanza di IEnumerable<TSource>
, ad esempio sequence.IsEmpty
. I membri nel secondo blocco di estensione vengono chiamati come se fossero membri statici di IEnumerable<TSource>
, ad esempio IEnumerable<int>.Identity
.
Per altre informazioni, leggere l'articolo sui membri dell'estensione nella guida alla programmazione, l'articolo di riferimento sul linguaggio sulla extension
parola chiave e la specifica delle funzionalità per la nuova funzionalità dei membri dell'estensione.
Parola chiave field
Il token field
consente di scrivere un corpo della funzione di accesso alle proprietà senza dichiarare un campo sottostante esplicito. Il token field
viene sostituito con un campo sottostante sintetizzato dal compilatore.
Ad esempio, in precedenza, se si vuole assicurarsi che una string
proprietà non possa essere impostata su null
, è necessario dichiarare un campo sottostante e implementare entrambe le funzioni di accesso:
private string _msg;
public string Message
{
get => _msg;
set => _msg = value ?? throw new ArgumentNullException(nameof(value));
}
È ora possibile semplificare il codice per:
public string Message
{
get;
set => field = value ?? throw new ArgumentNullException(nameof(value));
}
È possibile dichiarare un corpo per una o entrambe le funzioni di accesso per una proprietà supportata dal campo.
C'è la possibilità di un cambiamento significativo o confusione nella lettura del codice nei tipi che includono anche un simbolo denominato field
. È possibile usare @field
o this.field
per disambiguare tra la field
parola chiave e l'identificatore oppure rinominare il simbolo corrente field
per fornire una distinzione migliore.
Se si prova questa funzionalità e si hanno commenti e suggerimenti, commentare il problema di funzionalità nel csharplang
repository.
La parola chiave contestuale field
si trova in C# 13 come funzionalità di anteprima.
Conversioni implicite dell'intervallo
C# 14 introduce il supporto di prima classe per System.Span<T> e System.ReadOnlySpan<T> nel linguaggio. Questo supporto prevede nuove conversioni implicite che consentono una programmazione più naturale con questi tipi.
Span<T>
e ReadOnlySpan<T>
vengono usati in molti modi chiave in C# e nel runtime. L'introduzione migliora le prestazioni senza rischiare la sicurezza. C# 14 riconosce la relazione e supporta alcune conversioni tra ReadOnlySpan<T>
, Span<T>
e T[]
. I tipi span possono essere ricevitori di metodi di estensione, comporre con altre conversioni e semplificare gli scenari di inferenza dei tipi generici.
È possibile trovare l'elenco delle conversioni implicite nell'intervallo nell'articolo sui tipi predefiniti nella sezione delle informazioni di riferimento sul linguaggio. Puoi ottenere ulteriori dettagli leggendo la specifica della funzionalità per i tipi di intervallo di prima classe.
Tipi generici non associati e nameof
A partire da C# 14, l'argomento a nameof
può essere un tipo generico non vincolato. Ad esempio, nameof(List<>)
restituisce List
. Nelle versioni precedenti di C# è possibile usare solo tipi generici chiusi, ad esempio List<int>
, per restituire il List
nome.
Semplici parametri lambda con modificatori
È possibile aggiungere modificatori di parametri, ad esempio scoped
, ref
in
, out
, o ref readonly
ai parametri dell'espressione lambda senza specificare il tipo di parametro:
delegate bool TryParse<T>(string text, out T result);
// ...
TryParse<int> parse1 = (text, out result) => Int32.TryParse(text, out result);
In precedenza, l'aggiunta di eventuali modificatori era consentita solo quando le dichiarazioni di parametro includevano i tipi per i parametri. La dichiarazione precedente richiede i tipi in tutti i parametri:
TryParse<int> parse2 = (string text, out int result) => Int32.TryParse(text, out result);
Il params
modificatore richiede comunque un elenco di parametri tipizzato in modo esplicito.
Per altre informazioni su queste modifiche, vedere l'articolo sulle espressioni lambda nelle informazioni di riferimento sul linguaggio C#.
Più membri parziali
È ora possibile dichiarare costruttori di istanza ed eventi come membri parziali.
I costruttori parziali e gli eventi parziali devono includere esattamente una dichiarazione di definizione e una dichiarazione di implementazione.
Solo la dichiarazione di implementazione di un costruttore parziale può includere un inizializzatore del costruttore: this()
o base()
. Una sola dichiarazione di tipo parziale può includere la sintassi del costruttore primario.
La dichiarazione di implementazione di un evento parziale deve includere gli accessori add
e remove
. La dichiarazione di definizione dichiara un evento simile a un campo.
Assegnazione composta definita dall'utente
Per altre informazioni, vedere la specifica delle funzionalità per l'assegnazione composta definita dall'utente.
Assegnazione null-condizionale
Gli operatori di accesso ai membri condizionali Null, ?.
e ?[]
, ora possono essere usati sul lato sinistro di un'assegnazione semplice o composta.
Prima di C# 14, era necessario verificare la presenza di valori nulli in una variabile prima di assegnarla a una proprietà.
if (customer is not null)
{
customer.Order = GetCurrentOrder();
}
È possibile semplificare il codice precedente usando l'operatore ?.
:
customer?.Order = GetCurrentOrder();
Il lato destro dell'operatore =
viene valutato solo quando il lato sinistro non è Null. Se customer
è Null, il codice non chiama GetCurrentOrder
.
Oltre all'assegnazione, è possibile usare operatori di accesso ai membri condizionali al valore null con operatori di assegnazione composta (+=
, -=
e altri). Tuttavia, l'incremento e il decremento e ++
--
, non sono consentiti.
Per altre informazioni, vedere l'articolo di riferimento sul linguaggio sull'accesso ai membri condizionali e la specifica della funzionalità per l'assegnazione condizionale Null.