Null értékű értéktípusok (C# hivatkozás)

A null értékű értékekT? a mögöttes értéktípusT ö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, falsevagy 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 truefalse. Egyes alkalmazásokban azonban a változó értéke meghatározatlan vagy hiányzik. Az adatbázismezők truefalsetartalmazhatnak vagy , vagy egyáltalán nem tartalmazhatnak értéket, NULLazaz. 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 nullalapé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:

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 nullkí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; nullellenkező 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 az nulleredmény, akkor 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 falsemiatt 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égi operátor== esetében, ha mindkét operandus aznull, akkor az eredmény true– ha csak az egyik operandus null– 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ípus T 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 Tjelö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ölveObjecta 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:

Lásd még