Typy hodnot s možnou hodnotou null (referenční dokumentace jazyka C#)

Typ T?hodnoty s možnou hodnotou null představuje všechny hodnoty jeho základního typuT hodnoty a další hodnotu null. K proměnné můžete například přiřadit některou bool? z následujících tří hodnot: true, nebo falsenull. Základní typ T hodnoty nemůže být samotný typ hodnoty null.

Libovolný typ hodnoty null je instance obecné System.Nullable<T> struktury. Můžete odkazovat na typ hodnoty null s podkladovým typem T v některé z následujících zaměnitelných formulářů: Nullable<T> nebo T?.

Typ hodnoty null obvykle používáte, pokud potřebujete reprezentovat nedefinovanou hodnotu základního typu hodnoty. Například logická hodnota nebo boolproměnná může být pouze nebo truefalse. V některých aplikacích ale může být proměnná hodnota nedefinovaná nebo chybí. Například pole databáze může obsahovat nebo falsenebo nesmí obsahovat true žádnou hodnotu, tjNULL. . Typ můžete použít bool? v tomto scénáři.

Deklarace a přiřazení

Vzhledem k tomu, že typ hodnoty je implicitně konvertovatelný na odpovídající typ hodnoty null, můžete přiřadit hodnotu proměnné typu hodnoty s možnou hodnotou null, jak byste to udělali pro jeho základní typ hodnoty. Můžete také přiřadit null hodnotu. Příklad:

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];

Výchozí hodnota typu hodnoty null představuje null, to znamená instance, jejíž Nullable<T>.HasValue vlastnost vrátí false.

Prozkoumání instance typu hodnoty s možnou hodnotou null

Operátor se vzorem typu můžete použítis k prozkoumání instance typu null hodnoty s možnou hodnotou null a načtení hodnoty základního typu:

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

K prozkoumání a získání hodnoty proměnné typu hodnota s možnou hodnotou null můžete vždy použít následující vlastnosti jen pro čtení:

Následující příklad používá HasValue vlastnost k otestování, zda proměnná obsahuje hodnotu před zobrazením:

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

Můžete také porovnat proměnnou typu null hodnoty s možnou hodnotou null místo použití HasValue vlastnosti, jak ukazuje následující příklad:

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

Převod z typu hodnoty s možnou hodnotou null na podkladový typ

Pokud chcete přiřadit hodnotu typu hodnoty s možnou hodnotou null proměnné typu nenulable, možná budete muset zadat hodnotu, která má být přiřazena místo null. K tomu použijte operátor ??null-coalescing (můžete také použít metodu Nullable<T>.GetValueOrDefault(T) pro stejný účel):

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

Pokud chcete použít výchozí hodnotu základního typu hodnoty místo null, použijte metodu Nullable<T>.GetValueOrDefault() .

Můžete také explicitně přetypovat typ hodnoty null na nenulový typ, jak ukazuje následující příklad:

int? n = null;

//int m1 = n;    // Doesn't compile
int n2 = (int)n; // Compiles, but throws an exception if n is null

Pokud je nullhodnota typu hodnoty null za běhu, explicitní přetypování vyvolá InvalidOperationExceptionvýjimku .

Typ T hodnoty, který nemá hodnotu null, je implicitně převést na odpovídající typ T?hodnoty nullable .

Lifted operators

Předdefinované unární a binární operátory nebo všechny přetížené operátory podporované typem T hodnoty jsou podporovány také odpovídajícím typem T?hodnoty nullable . Tyto operátory, označované také jako zvedané operátory, vytvoří null , pokud jeden nebo oba operandy jsou null; jinak operátor použije k výpočtu výsledku obsažené hodnoty svých operandů. Příklad:

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

Poznámka

bool? Pro typ předdefinované & operátory a | operátory nesledují pravidla popsaná v této části: výsledek vyhodnocení operátoru může být nenulový, i když je nullněkterý z operandů . Další informace naleznete v části Logické operátory logické operátory s možnou hodnotou Null v článku logických operátorů .

Pro relační operátory<, >, <=a >=, pokud jeden nebo oba operandy jsou null, výsledek je false; v opačném případě jsou porovnány obsažené hodnoty operandů. Nepředpokládáme, že vzhledem k tomu, že určité porovnání (například<=) vrátí false, vrátí trueopačné porovnání (>) . Následující příklad ukazuje, že 10 je

  • ani větší než nebo rovno null
  • ani menší než 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

Pro operátor== rovnosti platí, že pokud jsou nulloba operandy , výsledek je true, pokud je nullpouze jeden z operandů , výsledek je false; v opačném případě jsou porovnány hodnoty obsažených operandů.

Pro operátor !=nerovnosti, pokud jsou oba operandy null, výsledek je false, pokud je pouze jeden z operandů null, výsledek je true; v opačném případě jsou porovnány obsažené hodnoty operandů.

Pokud existuje uživatelsky definovaný převod mezi dvěma typy hodnot, lze stejný převod použít také mezi odpovídajícími typy hodnot s možnou hodnotou null.

Boxing a unboxing

Instance typu T? hodnoty s možnou hodnotou null je zadána takto:

  • Pokud HasValue se vrátí false, vytvoří se odkaz na hodnotu null.
  • Pokud HasValue se vrátí true, odpovídající hodnota základního typu T hodnoty je boxována, nikoli instance Nullable<T>.

Pole typu hodnoty T můžete rozbalit na odpovídající typ T?hodnoty s možnou hodnotou null, jak ukazuje následující příklad:

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

Jak identifikovat typ hodnoty s možnou hodnotou null

Následující příklad ukazuje, jak určit, zda System.Type instance představuje vytvořený typ hodnoty null, to znamená System.Nullable<T> typ se zadaným parametrem Ttypu:

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

Jak ukazuje příklad, k vytvoření System.Type instance použijete operátor typeof.

Pokud chcete zjistit, jestli je instance typu hodnoty null, nepoužívejte metodu Object.GetTypeType k získání instance, která se má testovat s předchozím kódem. Když voláte metodu Object.GetType pro instanci typu hodnoty null, instance je v poli .Object Jako boxing instance nenulové instance typu hodnoty null je ekvivalentní k boxování hodnoty základního typu, GetType vrátí Type instanci, která představuje základní typ typu hodnoty nullable:

int? a = 17;
Type typeOfA = a.GetType();
Console.WriteLine(typeOfA.FullName);
// Output:
// System.Int32

Operátor is také nepoužívejte k určení, jestli je instance typu hodnoty null. Jak ukazuje následující příklad, nemůžete rozlišovat typy instance typu hodnot s možnou hodnotou null a její základní instanci typu pomocí operátoru 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?

Místo toho pomocí Nullable.GetUnderlyingType z prvního příkladu a operátoru typeof zkontrolujte, jestli je instance typu hodnoty null.

Poznámka

Metody popsané v této části se nevztahují v případě referenčních typů s možnou hodnotou null.

specifikace jazyka C#

Další informace najdete v následujících částech specifikace jazyka C#:

Viz také