Typen null-waarden (C#-verwijzing)
Een waardetype T?
dat null kan worden gebruikt, vertegenwoordigt alle waarden van het onderliggende waardetype T
en een extra null-waarde. U kunt bijvoorbeeld een van de volgende drie waarden toewijzen aan een bool?
variabele: true
, false
of null
. Een onderliggend waardetype T
kan geen type null-waarde zelf zijn.
Een null-waardetype is een exemplaar van de algemene System.Nullable<T> structuur. U kunt verwijzen naar een type null-waarde met een onderliggend type T
in een van de volgende uitwisselbare formulieren: Nullable<T>
of T?
.
Normaal gesproken gebruikt u een type null-waarde wanneer u de niet-gedefinieerde waarde van een onderliggend waardetype moet weergeven. Een Booleaanse waarde of bool
variabele kan bijvoorbeeld alleen true
een of false
. In sommige toepassingen kan een variabele waarde echter niet gedefinieerd of ontbreken. Een databaseveld kan bijvoorbeeld een waarde bevatten of false
, of het kan helemaal geen waarde bevattentrue
, dat wil NULL
gezegd. U kunt het bool?
type in dat scenario gebruiken.
Declaratie en toewijzing
Omdat een waardetype impliciet wordt omgezet in het bijbehorende type null-waarde, kunt u een waarde toewijzen aan een variabele van een type null-waarde zoals u dat zou doen voor het onderliggende waardetype. U kunt ook de null
waarde toewijzen. Voorbeeld:
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];
De standaardwaarde van een type null-waarde vertegenwoordigt, dat wil null
gezegd, het is een exemplaar waarvan Nullable<T>.HasValue de eigenschap als resultaat geeft false
.
Onderzoek van een exemplaar van een type null-waarde
U kunt de is
operator met een typepatroon gebruiken om zowel een exemplaar van een null-waardetype te onderzoeken als null
een waarde van een onderliggend type op te halen:
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
U kunt altijd de volgende alleen-lezen eigenschappen gebruiken om een waarde van een variabele van het type null-waarde te onderzoeken en op te halen:
Nullable<T>.HasValue geeft aan of een exemplaar van een type null-waarde een waarde heeft van het onderliggende type.
Nullable<T>.Value haalt de waarde van een onderliggend type op als HasValue dat het is
true
. Als HasValue dat het isfalse
, gooit de Value eigenschap een InvalidOperationException.
In het volgende voorbeeld wordt de HasValue
eigenschap gebruikt om te testen of de variabele een waarde bevat voordat deze wordt weergegeven:
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
U kunt ook een variabele van een type null-waarde vergelijken met null
in plaats van de HasValue
eigenschap te gebruiken, zoals in het volgende voorbeeld wordt weergegeven:
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
Conversie van een waardetype met null-waarde naar een onderliggend type
Als u een waarde van een type null-waarde wilt toewijzen aan een variabele voor een niet-null-waardetype, moet u mogelijk de waarde opgeven die moet worden toegewezen in plaats van null
. Gebruik de operator ??
null-coalescing om dat te doen (u kunt ook de Nullable<T>.GetValueOrDefault(T) methode voor hetzelfde doel gebruiken):
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
Als u de standaardwaarde van het onderliggende waardetype in plaats van null
wilt gebruiken, gebruikt u de Nullable<T>.GetValueOrDefault() methode.
U kunt ook expliciet een type null-waarde naar een niet-null-type casten, zoals in het volgende voorbeeld wordt weergegeven:
int? n = null;
//int m1 = n; // Doesn't compile
int n2 = (int)n; // Compiles, but throws an exception if n is null
Als de waarde van een type null-waarde in runtime is null
, genereert de expliciete cast een InvalidOperationException.
Een niet-null-waardetype T
wordt impliciet omgezet in het bijbehorende type T?
null-waarde.
Lifted operators
De vooraf gedefinieerde unaire en binaire operatoren of overbelaste operators die worden ondersteund door een waardetype T
, worden ook ondersteund door het bijbehorende type null-waarde T?
. Deze operators, ook wel lifted operators genoemd, produceren null
als een of beide operanden zijnnull
; anders gebruikt de operator de ingesloten waarden van de operanden om het resultaat te berekenen. Bijvoorbeeld:
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
Notitie
Voor het bool?
type voldoen de vooraf gedefinieerde &
operatoren |
niet aan de regels die in deze sectie worden beschreven: het resultaat van een operatorevaluatie kan niet null zijn, zelfs als een van de operanden is null
. Zie de sectie Logische Booleaanse operatoren van het artikel Booleaanse logische operators voor meer informatie.
Voor de vergelijkingsoperatoren <
, >
en <=
, als >=
een of beide operanden zijn null
, is false
het resultaat ; anders worden de ingesloten waarden van operanden vergeleken. Neem niet aan dat omdat een bepaalde vergelijking (bijvoorbeeld <=
) retourneert , de tegenovergestelde vergelijking (>
) retourneert false
true
. In het volgende voorbeeld ziet u dat 10 is
- niet groter dan of gelijk aan
null
- niet kleiner dan
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
Als beide operanden voor de gelijkheidsoperator ==
het resultaat zijnnull
, is true
het resultaat , als slechts één van de operanden het resultaat is false
null
, anders worden de ingesloten waarden van operanden vergeleken.
Als beide operanden voor de ongelijkheidsoperator !=
het resultaat zijn, is false
het resultaat , als slechts één van de operanden is null
, het resultaat ; true
anders worden de ingesloten waarden van operanden vergelekennull
.
Als er een door de gebruiker gedefinieerde conversie bestaat tussen twee waardetypen, kan dezelfde conversie ook worden gebruikt tussen de bijbehorende typen null-waarden.
Boksen en uitpakken
Een exemplaar van een type null-waarde T?
wordt als volgt in een vak geplaatst :
- Als HasValue er een resultaat wordt
false
geretourneerd, wordt de null-verwijzing geproduceerd. - Als HasValue het resultaat wordt
true
geretourneerd, wordt de bijbehorende waarde van het onderliggende waardetypeT
in een vak geplaatst, niet het exemplaar van Nullable<T>.
U kunt een waarde in een vak van een waardetype T
opheffen voor het bijbehorende type T?
null-waarde, zoals in het volgende voorbeeld wordt weergegeven:
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
Een type null-waarde identificeren
In het volgende voorbeeld ziet u hoe u kunt bepalen of een System.Type exemplaar een samengesteld null-waardetype vertegenwoordigt, dat wil weten het System.Nullable<T> type met een opgegeven typeparameter 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
Zoals in het voorbeeld wordt weergegeven, gebruikt u de typeof-operator om een System.Type exemplaar te maken.
Als u wilt bepalen of een exemplaar van een type null-waarde is, gebruikt u de Object.GetType methode niet om een Type exemplaar te laten testen met de voorgaande code. Wanneer u de Object.GetType methode aanroept op een exemplaar van een type null-waarde, wordt het exemplaar in een vak geplaatst.Object Als boksen van een niet-null-exemplaar van een null-waardetype gelijk is aan het boksen van een waarde van het onderliggende type, GetType retourneert u een Type exemplaar dat het onderliggende type van een null-waardetype vertegenwoordigt:
int? a = 17;
Type typeOfA = a.GetType();
Console.WriteLine(typeOfA.FullName);
// Output:
// System.Int32
Gebruik ook niet de operator is om te bepalen of een exemplaar van een null-waardetype is. Zoals in het volgende voorbeeld wordt weergegeven, kunt u geen typen van een exemplaar van een null-waardetype en het onderliggende typeexemplaren onderscheiden met de is
operator:
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?
Gebruik in plaats daarvan de Nullable.GetUnderlyingType operator uit het eerste voorbeeld en het typeof-operator om te controleren of een exemplaar van een null-waardetype is.
Notitie
De methoden die in deze sectie worden beschreven, zijn niet van toepassing in het geval van null-referentietypen.
C#-taalspecificatie
Zie de volgende secties van de C#-taalspecificatie voor meer informatie:
- Null-typen
- Lifted operators
- Impliciete null-conversies
- Expliciete null-conversies
- Operators voor lifted conversie