Tipi di riferimento Nullable (riferimenti per C#)Nullable reference types (C# reference)

Nota

Questo articolo illustra i tipi di riferimento Nullable.This article covers nullable reference types. È anche possibile dichiarare i tipi di valore Nullable.You can also declare nullable value types.

I tipi di riferimento nullable sono disponibili a partire da C# 8,0, nel codice che ha acconsentito a un contesto in grado di riconoscere i valori null.Nullable reference types are available beginning with C# 8.0, in code that has opted in to a nullable aware context. I tipi di riferimento Nullable, gli avvisi di analisi statica null e l' operatore con indulgenza null sono funzionalità del linguaggio facoltative.Nullable reference types, the null static analysis warnings, and the null-forgiving operator are optional language features. Tutti sono spenti per impostazione predefinita.All are turned off by default. Un contesto Nullable è controllato a livello di progetto usando le impostazioni di compilazione o nel codice che usa pragma.A nullable context is controlled at the project level using build settings, or in code using pragmas.

In un contesto compatibile con Nullable:In a nullable aware context:

  • Una variabile di un tipo di riferimento T deve essere inizializzata con un valore diverso da null e non può mai essere assegnato un valore che può essere null .A variable of a reference type T must be initialized with non-null, and may never be assigned a value that may be null.
  • Una variabile di un tipo riferimento T? può essere inizializzata con null o assegnato null , ma è necessario eseguire il controllo null prima di dereferenziare.A variable of a reference type T? may be initialized with null or assigned null, but is required to be checked against null before de-referencing.
  • Una variabile m di tipo T? viene considerata non null quando si applica l'operatore con indulgenza null, come in m! .A variable m of type T? is considered to be non-null when you apply the null-forgiving operator, as in m!.

Le distinzioni tra un tipo di riferimento non Nullable T e un tipo di riferimento Nullable T? vengono applicate dall'interpretazione del compilatore delle regole precedenti.The distinctions between a non-nullable reference type T and a nullable reference type T? are enforced by the compiler's interpretation of the preceding rules. Una variabile di tipo T e una variabile di tipo T? sono rappresentate dallo stesso tipo .NET.A variable of type T and a variable of type T? are represented by the same .NET type. Nell'esempio seguente viene dichiarata una stringa che non ammette i valori null e una stringa Nullable, quindi viene utilizzato l'operatore che perdona i valori null per assegnare un valore a una stringa non nullable:The following example declares a non-nullable string and a nullable string, and then uses the null-forgiving operator to assign a value to a non-nullable string:

string notNull = "Hello";
string? nullable = default;
notNull = nullable!; // null forgiveness

Le variabili notNull e nullable sono entrambe rappresentate dal String tipo.The variables notNull and nullable are both represented by the String type. Poiché i tipi non nullable e nullable sono entrambi archiviati come lo stesso tipo, esistono diverse posizioni in cui l'utilizzo di un tipo di riferimento nullable non è consentito.Because the non-nullable and nullable types are both stored as the same type, there are several locations where using a nullable reference type isn't allowed. In generale, non è possibile usare un tipo di riferimento nullable come classe base o interfaccia implementata.In general, a nullable reference type can't be used as a base class or implemented interface. Non è possibile usare un tipo di riferimento nullable in nessuna creazione di oggetti o espressione di test del tipo.A nullable reference type can't be used in any object creation or type testing expression. Un tipo di riferimento nullable non può essere il tipo di un'espressione di accesso ai membri.A nullable reference type can't be the type of a member access expression. Gli esempi seguenti illustrano questi costrutti:The following examples show these constructs:

public MyClass : System.Object? // not allowed
{
}

var nullEmpty = System.String?.Empty; // Not allowed
var maybeObject = new object?(); // Not allowed
try
{
    if (thing is string? nullableString) // not allowed
        Console.WriteLine(nullableString);
} catch (Exception? e) // Not Allowed
{
    Console.WriteLine("error");
}

Riferimenti nullable e analisi staticaNullable references and static analysis

Negli esempi della sezione precedente viene illustrata la natura dei tipi di riferimento Nullable.The examples in the previous section illustrate the nature of nullable reference types. I tipi di riferimento nullable non sono nuovi tipi di classe, ma piuttosto annotazioni sui tipi di riferimento esistenti.Nullable reference types aren't new class types, but rather annotations on existing reference types. Il compilatore usa tali annotazioni per individuare potenziali errori di riferimento null nel codice.The compiler uses those annotations to help you find potential null reference errors in your code. Non esiste alcuna differenza di runtime tra un tipo di riferimento non nullable e un tipo di riferimento Nullable.There's no runtime difference between a non-nullable reference type and a nullable reference type. Il compilatore non aggiunge alcun controllo di runtime per i tipi di riferimento che non ammettono valori null.The compiler doesn't add any runtime checking for non-nullable reference types. I vantaggi si trovano nell'analisi in fase di compilazione.The benefits are in the compile-time analysis. Il compilatore genera avvisi che consentono di individuare e correggere gli errori null potenziali nel codice.The compiler generates warnings that help you find and fix potential null errors in your code. Si dichiara lo scopo e il compilatore avvisa l'utente quando il codice viola tale finalità.You declare your intent, and the compiler warns you when your code violates that intent.

In un contesto abilitato Nullable, il compilatore esegue l'analisi statica su variabili di qualsiasi tipo di riferimento, Nullable e non nullable.In a nullable enabled context, the compiler performs static analysis on variables of any reference type, both nullable and non-nullable. Il compilatore tiene traccia dello stato null di ogni variabile di riferimento come not null o Maybe null.The compiler tracks the null state of each reference variable as either not null or maybe null. Lo stato predefinito di un riferimento non nullable non è null.The default state of a non-nullable reference is not null. Lo stato predefinito di un riferimento Nullable è forse null.The default state of a nullable reference is maybe null.

I tipi di riferimento che non ammettono valori null devono essere sempre sicuri per la dereferenziazione perché lo stato null non è null.Non-nullable reference types should always be safe to dereference because their null state is not null. Per applicare questa regola, il compilatore genera avvisi se un tipo di riferimento non nullable non è inizializzato su un valore non null.To enforce that rule, the compiler issues warnings if a non-nullable reference type isn't initialized to a non-null value. Le variabili locali devono essere assegnate dove sono dichiarate.Local variables must be assigned where they're declared. Ogni costruttore deve assegnare ogni campo, nel corpo, un costruttore chiamato, o usando un inizializzatore di campo.Every constructor must assign every field, either in its body, a called constructor, or using a field initializer. Il compilatore genera avvisi se un riferimento non nullable viene assegnato a un riferimento il cui stato è forse null.The compiler issues warnings if a non-nullable reference is assigned to a reference whose state is maybe null. Tuttavia, poiché un riferimento che non ammette i valori null non è null, non viene emesso alcun avviso quando si fa riferimento a tali variabili.However, because a non-nullable reference is not null, no warnings are issued when those variables are de-referenced.

I tipi di riferimento nullable possono essere inizializzati o assegnati a null .Nullable reference types may be initialized or assigned to null. Pertanto, l'analisi statica deve determinare che una variabile non è null prima che venga dereferenziata.Therefore, static analysis must determine that a variable is not null before it's dereferenced. Se un riferimento Nullable è determinato come null, non può essere assegnato a una variabile di riferimento che non ammette i valori null.If a nullable reference is determined to be maybe null, it can't be assigned to a non-nullable reference variable. La classe seguente mostra esempi di questi avvisi:The following class shows examples of these warnings:

public class ProductDescription
{
    private string shortDescription;
    private string? detailedDescription;

    public ProductDescription() // Warning! short description not initialized.
    {
    }

    public ProductDescription(string productDescription) =>
        this.shortDescription = productDescription;

    public void SetDescriptions(string productDescription, string? details=null)
    {
        shortDescription = productDescription;
        detailedDescription = details;
    }

    public string GetDescription()
    {
        if (detailedDescription.Length == 0) // Warning! dereference possible null
        {
            return shortDescription;
        }
        else
        {
            return $"{shortDescription}\n{detailedDescription}";
        }
    }

    public string FullDescription()
    {
        if (detailedDescription == null)
        {
            return shortDescription;
        }
        else if (detailedDescription.Length > 0) // OK, detailedDescription can't be null.
        {
            return $"{shortDescription}\n{detailedDescription}";
        }
        return shortDescription;
    }
}

Il frammento di codice seguente mostra dove il compilatore emette avvisi quando si usa questa classe:The following snippet shows where the compiler emits warnings when using this class:

string shortDescription = default; // Warning! non-nullable set to null;
var product = new ProductDescription(shortDescription); // Warning! static analysis knows shortDescription maybe null.

string description = "widget";
var item = new ProductDescription(description);

item.SetDescriptions(description, "These widgets will do everything.");

Gli esempi precedenti illustrano l'analisi statica del compilatore per determinare lo stato null delle variabili di riferimento.The preceding examples demonstrate the compiler's static analysis to determine the null state of reference variables. Il compilatore applica le regole del linguaggio per i controlli null e le assegnazioni per informare l'analisi.The compiler applies language rules for null checks and assignments to inform its analysis. Il compilatore non può fare supposizioni sulla semantica di metodi o proprietà.The compiler can't make assumptions about the semantics of methods or properties. Se si chiamano metodi che eseguono controlli null, il compilatore non sa che questi metodi influiscono sullo stato null di una variabile.If you call methods that perform null checks, the compiler can't know those methods affect a variable's null state. Sono disponibili diversi attributi che è possibile aggiungere alle API per informare il compilatore sulla semantica di argomenti e valori restituiti.There are a number of attributes you can add to your APIs to inform the compiler about the semantics of arguments and return values. Questi attributi sono stati applicati a molte API comuni nelle librerie .NET Core.These attributes have been applied to many common APIs in the .NET Core libraries. Ad esempio, IsNullOrEmpty è stato aggiornato e il compilatore interpreta correttamente tale metodo come un controllo null.For example, IsNullOrEmpty has been updated, and the compiler correctly interprets that method as a null check. Per ulteriori informazioni sugli attributi applicabili all'analisi statica dello stato null, vedere l'articolo sugli attributi Nullable.For more information about the attributes that apply to null state static analysis, see the article on Nullable attributes.

Impostazione del contesto NullableSetting the nullable context

Esistono due modi per controllare il contesto Nullable.There are two ways to control the nullable context. A livello di progetto, è possibile aggiungere l' <Nullable>enable</Nullable> impostazione del progetto.At the project level, you can add the <Nullable>enable</Nullable> project setting. In un singolo file di origine C# è possibile aggiungere il #nullable enable pragma per abilitare il contesto Nullable.In a single C# source file, you can add the #nullable enable pragma to enable the nullable context. Vedere l'articolo sull' impostazione di una strategia Nullable.See the article on setting a nullable strategy.

Specifiche del linguaggio C#C# language specification

Per ulteriori informazioni, vedere le seguenti proposte per la specifica del linguaggio C#:For more information, see the following proposals for the C# language specification:

Vedere ancheSee also