Null értékű értéktípusok (C# hivatkozás)
A null értékű értékek T?
a mögöttes értéktípus T
összes értékét és egy további null értéket jelölnek. A következő három érték bármelyikét hozzárendelheti például egy bool?
változóhoz: true
, false
vagy null
. Az alapul szolgáló értéktípus T
maga nem lehet null értékű.
Bármely null értékű értéktípus az általános System.Nullable<T> struktúra egy példánya. Az alábbi felcserélhető űrlapok bármelyikében hivatkozhat egy null értékű értéktípusra, amelynek mögöttes típusa T
van: Nullable<T>
vagy T?
.
Általában null értékű típust használ, ha egy mögöttes értéktípus nem definiált értékét kell jelölnie. Logikai vagy bool
, változó például csak vagy csak lehet true
false
. Egyes alkalmazásokban azonban a változó értéke meghatározatlan vagy hiányzik. Az adatbázismezők true
false
tartalmazhatnak vagy , vagy egyáltalán nem tartalmazhatnak értéket, NULL
azaz. Ebben a forgatókönyvben használhatja a bool?
típust.
Deklaráció és hozzárendelés
Mivel az értéktípus implicit módon konvertálható a megfelelő null értékű típusra, a null értékű típusú változókhoz ugyanúgy rendelhet értéket, mint a mögöttes értéktípus esetében. Az értéket is hozzárendelheti null
. Példa:
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];
A null értékű típus null
alapértelmezett értéke egy olyan példány, amelynek Nullable<T>.HasValue a tulajdonsága ad vissza false
.
Null értékű példány vizsgálata
Az operátor típusmintával megvizsgálhatja a null értékű típus null
egy példányát, és lekérhet is
egy mögöttes típusú értéket:
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
A következő írásvédett tulajdonságok használatával mindig megvizsgálhatja és lekérheti a null értékű érték típusú változó értékét:
Nullable<T>.HasValue azt jelzi, hogy egy null értékű típusú példány rendelkezik-e annak alapjául szolgáló értékkel.
Nullable<T>.Valueegy mögöttes típus értékét kapja meg, ha HasValue az .
true
Ha HasValue igenfalse
, a Value tulajdonság egy InvalidOperationException.
Az alábbi példa a tulajdonságot használja annak HasValue
tesztelésére, hogy a változó tartalmaz-e értéket a megjelenítés előtt:
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
Egy null értékű null
változót is összehasonlíthat a HasValue
tulajdonság használata helyett, ahogy az az alábbi példában látható:
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
Konvertálás null értékű értéktípusról mögöttes típusra
Ha nem null értékű értéktípusú értéket szeretne hozzárendelni egy nem null értékű változóhoz, előfordulhat, hogy meg kell adnia a hozzárendelni null
kívánt értéket. Ehhez használja a null-szenesítés operátort ??
(ugyanezt a Nullable<T>.GetValueOrDefault(T) módszert is használhatja):
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
Ha a mögöttes értéktípus alapértelmezett értékét szeretné használni a helyett null
, használja a metódust Nullable<T>.GetValueOrDefault() .
A null értékű típusokat explicit módon nem null értékű típusra is leadhatja, ahogy az az alábbi példában is látható:
int? n = null;
//int m1 = n; // Doesn't compile
int n2 = (int)n; // Compiles, but throws an exception if n is null
Futtatáskor, ha egy null értékű érték értéke az null
, az explicit leadás egy InvalidOperationException.
A nem null értékű értékek implicit T
módon konvertálhatók a megfelelő null értékű típusra T?
.
Emelt operátorok
Az előre definiált nem bináris és bináris operátorokat , illetve az értéktípus T
által támogatott túlterhelt operátorokat a megfelelő null értékű típus T?
is támogatja. Ezek az operátorok, más néven emelt operátorok akkor termelnek null
, ha az egyik vagy mindkét operandus; null
ellenkező esetben az operátor az operandusok tartalmazott értékeit használja az eredmény kiszámításához. Például:
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
Feljegyzés
bool?
A típus esetében az előre definiált &
és |
az operátorok nem követik az ebben a szakaszban leírt szabályokat: az operátorok kiértékelésének eredménye akkor is null értékű lehet, ha az egyik operandus az null
. További információkért tekintse meg a logikai operátorokról szóló cikk null értékű logikai operátorok szakaszát.
Az összehasonlító operátorok <
>
<=
esetében , és >=
ha az egyik vagy mindkét operandus, null
az eredményfalse
; ellenkező esetben az operandusok tartalmazott értékeit hasonlítjuk össze. Ne feltételezzük , hogy egy adott összehasonlítás (például <=
) visszaadása false
miatt az ellenkező összehasonlítás (>
) ad vissza true
. Az alábbi példa azt mutatja, hogy a 10
- nem nagyobb vagy egyenlő
null
- vagy kisebb, mint
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
Az egyenlőség operátor ==
esetében , ha mindkét operandus aznull
, akkor az eredmény true
, ha csak az egyik operandus, null
akkor az eredményfalse
; ellenkező esetben az operandusok tartalmazott értékeit hasonlítjuk össze.
Az egyenlőtlenségi operátor !=
esetében , ha mindkét operandus az null
, akkor az eredmény false
– ha csak az egyik operandus null
– az eredmény true
; ellenkező esetben az operandusok tartalmazott értékeit hasonlítjuk össze.
Ha két értéktípus között létezik felhasználó által definiált átalakítás , ugyanez a konverzió a megfelelő null értékű értéktípusok között is használható.
Boxing and unboxing
A null értékű típus T?
egy példánya a következőképpen van bekeretezve :
- Ha HasValue visszaadja
false
, a nullhivatkozás létrejön. - Ha HasValue visszaadja
true
, az alapul szolgáló értéktípusT
megfelelő értéke van bekeretezve, nem pedig a példánya Nullable<T>.
Egy értéktípus T
dobozos értékeit a megfelelő null értékű típusba T?
is ki lehet csomagolni, ahogy az alábbi példa is mutatja:
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
Null értékű értéktípus azonosítása
Az alábbi példa bemutatja, hogyan állapítható meg, hogy egy System.Type példány egy létrehozott null értékű típust, vagyis egy System.Nullable<T> megadott típusparamétert T
jelöl-e:
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
Ahogy a példa is mutatja, a típusművelet használatával hozhat létre példányt System.Type .
Ha meg szeretné állapítani, hogy egy példány null értékű-e, ne használja a Object.GetType metódust Type egy példány teszteléséhez az előző kóddal. Ha null értékű példányon hívja meg a Object.GetType metódust, a példány be van jelölve Objecta következőre: . Mivel egy null értékű értéktípus nem null értékű példányának dobozolása egyenértékű az alapul szolgáló típusú érték dobozolásával, egy olyan példányt Type ad vissza, GetType amely egy null értékű értéktípus alapjául szolgáló típust jelöl:
int? a = 17;
Type typeOfA = a.GetType();
Console.WriteLine(typeOfA.FullName);
// Output:
// System.Int32
Emellett ne használja az is operátort annak meghatározására, hogy egy példány null értékű-e. Az alábbi példában látható, hogy a null értékű érték típusú példányok és annak mögöttes típuspéldányai nem különböztethetők meg az is
operátorral:
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?
Ehelyett használja az Nullable.GetUnderlyingType első példa és típus operátort annak ellenőrzéséhez, hogy egy példány null értékű-e.
Feljegyzés
Az ebben a szakaszban ismertetett módszerek null értékű hivatkozástípusok esetén nem alkalmazhatók.
C# nyelvspecifikáció
További információt a C# nyelvspecifikációjának alábbi szakaszaiban talál:
- Null értékű típusok
- Emelt operátorok
- Implicit null értékű konverziók
- Explicit null értékű konverziók
- Emelt konverziós operátorok