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.
Un tipo valore che ammette i valori NullT? rappresenta tutti i valori del tipo valoreT sottostante e un valore null aggiuntivo. Ad esempio, è possibile assegnare uno dei tre valori seguenti a una variabile bool?: true, falseo null. Un tipo di T valore sottostante non può essere un tipo valore nullable.
Il riferimento al linguaggio C# documenta la versione rilasciata più di recente del linguaggio C#. Contiene anche la documentazione iniziale per le funzionalità nelle anteprime pubbliche per la versione futura del linguaggio.
La documentazione identifica tutte le funzionalità introdotte nelle ultime tre versioni della lingua o nelle anteprime pubbliche correnti.
Suggerimento
Per trovare quando una funzionalità è stata introdotta per la prima volta in C#, vedere l'articolo sulla cronologia delle versioni del linguaggio C#.
Qualsiasi tipo di valore nullable è un'istanza della struttura generica System.Nullable<T>. È possibile fare riferimento a un tipo valore nullable con un tipo T sottostante in uno dei formati intercambiabili seguenti: Nullable<T> o T?.
In genere, usare un tipo valore nullable quando è necessario rappresentare il valore non definito di un tipo valore sottostante. Ad esempio, una variabile booleana, o bool, può essere solo true o false. Tuttavia, in alcune applicazioni un valore di variabile può essere indefinito o mancante. Ad esempio, un campo di database può contenere true o oppure falsepotrebbe non contenere alcun valore, NULLovvero . È possibile usare il tipo bool? in tale scenario.
Dichiarazione e assegnazione
Poiché un tipo valore è convertibile in modo implicito nel tipo di valore nullable corrispondente, è possibile assegnare un valore a una variabile di un tipo valore nullable come si fa per il tipo di valore sottostante. È anche possibile assegnare il valore null. Ad esempio:
double? pi = 3.14;
char? letter = 'a';
int m2 = 10;
int? m = m2;
bool? flag = null;
// An array of a nullable value type:
int?[] arr = new int?[10];
Il valore predefinito di un tipo valore nullable rappresenta null. Si tratta di un'istanza la cui Nullable<T>.HasValue proprietà restituisce false.
Esame di un'istanza di un tipo valore nullable
Per controllare un'istanza di un tipo valore nullable per null e ottenere un valore di un tipo sottostante, usare l'operatoreis con un criterio di tipo:
int? a = 42;
if (a is int valueOfA)
{
Console.WriteLine($"a is {valueOfA}");
}
else
{
Console.WriteLine("a does not have a value");
}
// Output:
// a is 42
È sempre possibile usare le proprietà di sola lettura seguenti per controllare e ottenere un valore di una variabile di tipo valore nullable:
Nullable<T>.HasValue indica se un'istanza di un tipo valore nullable ha un valore del tipo sottostante.
Nullable<T>.Value ottiene il valore di un tipo sottostante se HasValue è
true. Se HasValue èfalse, la proprietà Value genera un'eccezione InvalidOperationException.
Nell'esempio seguente viene utilizzata la HasValue proprietà per verificare se la variabile contiene un valore prima di visualizzarlo:
int? b = 10;
if (b.HasValue)
{
Console.WriteLine($"b is {b.Value}");
}
else
{
Console.WriteLine("b does not have a value");
}
// Output:
// b is 10
È anche possibile confrontare una variabile di un tipo valore nullable con null anziché usare la proprietà HasValue, come illustrato nell'esempio seguente:
int? c = 7;
if (c != null)
{
Console.WriteLine($"c is {c.Value}");
}
else
{
Console.WriteLine("c does not have a value");
}
// Output:
// c is 7
Conversione da un tipo di valore nullable a un tipo sottostante
Se si vuole assegnare un valore di tipo valore nullable a una variabile di tipo valore non nullable, potrebbe essere necessario specificare il valore da assegnare al posto di null. Usare l'operatore ??null-coalescing per eseguire questa operazione. È anche possibile usare il Nullable<T>.GetValueOrDefault(T) metodo per lo stesso scopo:
int? a = 28;
int b = a ?? -1;
Console.WriteLine($"b is {b}"); // output: b is 28
int? c = null;
int d = c ?? -1;
Console.WriteLine($"d is {d}"); // output: d is -1
Se si vuole usare il valore predefinito del tipo di valore sottostante al posto di null, usare il metodo Nullable<T>.GetValueOrDefault().
È anche possibile eseguire il cast esplicito di un tipo valore nullable a un tipo non nullable, come illustrato nell'esempio seguente:
int? n = null;
//int m1 = n; // Doesn't compile
int n2 = (int)n; // Compiles, but throws an exception if n is null
Se in fase di esecuzione il valore di un tipo nullable è null, il cast esplicito genera un'eccezione InvalidOperationException.
Un tipo valore non nullable T viene convertito in modo implicito nel tipo di valore nullable corrispondente T?.
Operatori lifted
Un tipo valore T? nullable supporta gli operatori unari e binari predefiniti o qualsiasi operatore di overload supportato da un tipo valore T . Questi operatori, noti anche come operatori lifted, restituiscono null se uno o entrambi gli operandi sono null. In caso contrario, l'operatore utilizza i valori contenuti dei relativi operandi per calcolare il risultato. Ad esempio:
int? a = 10;
int? b = null;
int? c = 10;
a++; // a is 11
a = a * c; // a is 110
a = a + b; // a is null
Nota
Per il tipo bool?, gli operatori predefiniti & e | non si attengono alle regole descritte in questa sezione: il risultato di una valutazione degli operatori può essere non Null, anche se uno degli operandi è null. Per altre informazioni, vedere la sezione Operatori logici booleani nullable dell'articolo Operatori logici booleani.
Per gli operatori <di confronto, >, <=e >=, se uno o entrambi gli operandi sono null, il risultato è false. In caso contrario, vengono confrontati i valori contenuti degli operandi. Non presupporre che poiché un particolare confronto ( ad esempio , <=) restituisce false, il confronto opposto (>) restituisce true. L'esempio seguente mostra che 10
- non è né maggiore o uguale a
null - né minore di
null
int? a = 10;
Console.WriteLine($"{a} >= null is {a >= null}");
Console.WriteLine($"{a} < null is {a < null}");
Console.WriteLine($"{a} == null is {a == null}");
// Output:
// 10 >= null is False
// 10 < null is False
// 10 == null is False
int? b = null;
int? c = null;
Console.WriteLine($"null >= null is {b >= c}");
Console.WriteLine($"null == null is {b == c}");
// Output:
// null >= null is False
// null == null is True
Per l'operatore== di uguaglianza, se entrambi gli operandi sono null, il risultato è true. Se solo uno degli operandi è null, il risultato è false. In caso contrario, vengono confrontati i valori contenuti degli operandi.
Per l'operatore !=di disuguaglianza, se entrambi gli operandi sono null, il risultato è false. Se solo uno degli operandi è null, il risultato è true. In caso contrario, vengono confrontati i valori contenuti degli operandi.
Se esiste una conversione definita dall'utente tra due tipi valore, la stessa conversione può essere usata anche tra i tipi di valore nullable corrispondenti.
Boxing e unboxing
Quando si esegue una casella di un'istanza di un tipo T?valore nullable, si applicano le regole seguenti:
- Se HasValue restituisce
false, l'operazione boxing restituisce il riferimento Null. - Se HasValue restituisce
true, l'operazione boxing riquadri il valore corrispondente del tipo diTvalore sottostante, non l'istanza di Nullable<T>.
È possibile eseguire la conversione unboxing del tipo valore T sottoposto a boxing nel tipo valore nullable T? corrispondente, come illustrato nell'esempio seguente:
int a = 41;
object aBoxed = a;
int? aNullable = (int?)aBoxed;
Console.WriteLine($"Value of aNullable: {aNullable}");
object aNullableBoxed = aNullable;
if (aNullableBoxed is int valueOfA)
{
Console.WriteLine($"aNullableBoxed is boxed int: {valueOfA}");
}
// Output:
// Value of aNullable: 41
// aNullableBoxed is boxed int: 41
Procedura: Identificare un tipo valore nullable
Nell'esempio seguente viene illustrato come determinare se un'istanza System.Type rappresenta un tipo valore nullable costruito, ovvero il tipo System.Nullable<T> con un parametro di tipo specificato T:
Console.WriteLine($"int? is {(IsNullable(typeof(int?)) ? "nullable" : "non nullable")} value type");
Console.WriteLine($"int is {(IsNullable(typeof(int)) ? "nullable" : "non-nullable")} value type");
bool IsNullable(Type type) => Nullable.GetUnderlyingType(type) != null;
// Output:
// int? is nullable value type
// int is non-nullable value type
Come illustrato nell'esempio, si usa l'operatore typeof per creare un'istanza System.Type.
Se si vuole determinare se un'istanza è di un tipo valore nullable, non usare il Object.GetType metodo per ottenere un'istanza Type da testare usando il codice precedente. Quando si chiama il metodo Object.GetType in un'istanza di un tipo nullable, viene eseguita la conversione boxing dell'istanza a Object. Poiché la conversione boxing di un'istanza non Null di un tipo valore nullable equivale al boxing di un valore del tipo sottostante, GetType restituisce un'istanza Type che rappresenta il tipo sottostante di un tipo valore nullable:
int? a = 17;
Type typeOfA = a.GetType();
Console.WriteLine(typeOfA.FullName);
// Output:
// System.Int32
Inoltre, non usare l’operatore is per determinare se un'istanza è di un tipo valore nullable. Come illustrato nell'esempio seguente, non è possibile distinguere i tipi di un'istanza di tipo valore nullable e l'istanza del tipo sottostante usando l'operatore is :
int? a = 14;
if (a is int)
{
Console.WriteLine("int? instance is compatible with int");
}
int b = 17;
if (b is int?)
{
Console.WriteLine("int instance is compatible with int?");
}
// Output:
// int? instance is compatible with int
// int instance is compatible with int?
Usare invece il Nullable.GetUnderlyingType metodo del primo esempio e l'operatore typeof per verificare se un'istanza è di un tipo valore nullable.
Nota
I metodi descritti in questa sezione non si applicano ai tipi riferimento nullable.
Specifiche del linguaggio C#
Per altre informazioni, vedere le sezioni seguenti delle specifiche del linguaggio C#:
- Tipi nullable
- Operatori lifted
- Conversioni nullable implicite
- Conversioni nullable esplicite
- Operatori di conversione lifted