Typy hodnot s možnou hodnotou Null (Referenční informace pro C#)

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

Poznámka

Jazyk C# 8.0 zavádí funkci odkazových typů s možnou hodnotou null. Další informace najdete v tématu Odkazové typy s možnou hodnotou Null. Typy hodnot s možnou hodnotou null jsou k dispozici od jazyka C# 2.

Jakýkoli typ hodnoty s možnou hodnotou null je instancí obecné System.Nullable<T> struktury. Na typ hodnoty s možnou hodnotou null můžete odkazovat s podkladovým typem v kterékoli z T následujících zaměnitelných Nullable<T> forem: nebo T? .

Typ hodnoty s možnou hodnotou null se obvykle používá, když potřebujete reprezentovat nedefinované hodnoty základního typu hodnoty. Například logická hodnota nebo bool proměnná může být buď , true nebo false . V některých aplikacích však může být hodnota proměnné nedefinovaná nebo chybí. Například databázové pole může obsahovat nebo , nebo nemusí obsahovat vůbec žádnou true false hodnotu, to znamená NULL . V tomto bool? scénáři můžete použít typ .

Deklarace a přiřazení

Vzhledem k tomu, že typ hodnoty je implicitně převoditelný na odpovídající typ hodnoty s možnou hodnotou null, můžete přiřadit hodnotu proměnné typu hodnoty s možnou hodnotou null, jak byste to mohli udělat pro příslušný typ základní hodnoty. Hodnotu můžete také null přiřadit. Napří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 s možnou hodnotou null představuje , to znamená, že je to null instance, jejíž Nullable<T>.HasValue vlastnost vrací false .

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

Počínaje jazykem C# 7.0 is můžete pomocí operátoru se vzorem typu prozkoumat instanci typu hodnoty nullable pro a načíst hodnotu null 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 hodnoty 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á vlastnost HasValue k otestování, jestli 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ísto použití vlastnosti můžete také porovnat proměnnou typu s možnou hodnotou null, jak null HasValue 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 s možnou hodnotou null proměnné typu hodnota, která není nullable, možná budete muset zadat hodnotu, která se má přiřadit místo null . K tomu použijte operátor ?? nulového souprodeje (pro stejný účel můžete použít Nullable<T>.GetValueOrDefault(T) také metodu ):

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 místo použít výchozí hodnotu základního typu hodnoty null , použijte Nullable<T>.GetValueOrDefault() metodu .

Můžete také explicitně přetypovat typ hodnoty s možnou hodnotou null na typ, který nemůže mít hodnotu null, 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 hodnota typu s možnou hodnotou null za běhu , explicitní přetypování vyvolá null InvalidOperationException .

Typ hodnoty, který není nullable, T se implicitně převést na odpovídající hodnotový typ s možnou hodnotou null T? .

Zrušené operátory

Předdefinované unární a binární operátory nebo jakékoli přetížené operátory, které jsou podporovány typem hodnoty, jsou také podporovány odpovídajícím typem hodnoty T nullable T? . Tyto operátory, označované také jako operátory zrušené, vytvoří, pokud je jeden nebo oba operandy ; v opačném případě operátor použije obsažené hodnoty svých operandů k null null výpočtu výsledku. Napří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

Pro typ se předdefinované operátory a nedo souladu s pravidly popsanými v této části: výsledek vyhodnocení operátoru může být nenulový, i když bool? & je jeden z | operandů null . Další informace najdete v části Logické logické operátory s možnou hodnotou Null v článku Logické operátory s logickými operátory s povolenou hodnotou Null.

Pro operátory porovnání , , a , pokud je jeden nebo oba operandy , je výsledkem ; v opačném případě jsou porovnány < obsažené hodnoty > <= >= null false operandů. Nepřepokládejte, že vzhledem k tomu, že konkrétní porovnání (například ) vrací <= false , vrátí opačné porovnání ( > true ). 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

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

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

Pokud existuje uživatelem 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.

Balení a rozbalení

Instance typu hodnoty s možnou hodnotou null T? je krabicová následujícím způsobem:

  • Pokud HasValue vrátí hodnotu , je vytvořen false nulový odkaz.
  • Pokud vrátí hodnotu , odpovídající hodnota podkladového typu hodnoty je HasValue true T boxed, nikoli instance Nullable<T> .

Pole hodnot typu můžete zrušit na odpovídající hodnotový typ s možnou T hodnotou null, jak T? 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 zjistit, zda instance představuje vytvořený typ hodnoty nullable, to znamená typ s System.Type System.Nullable<T> parametrem zadaného typu 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

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

Pokud chcete určit, zda je instance typu s možnou hodnotou null, nepoužívejte metodu k získání instance, která se má testovat pomocí Object.GetType Type předchozího kódu. Když zavoláte metodu pro instanci typu hodnoty s možnou hodnotou Object.GetType null, instance je boxed to Object . Vzhledem k tomu, že balení jiné instance než null typu hodnoty s možnou hodnotou null je ekvivalentem balení hodnoty základního typu, vrátí instanci, která představuje základní typ typu hodnoty GetType Type nullable:

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

Také nepoužívejte operátor is k určení, jestli je instance typu s možnou hodnotou null. Jak ukazuje následující příklad, nelze rozlišit typy instance typu hodnoty s možnou hodnotou null a její základní instance typu pomocí is operátoru :

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?

Pomocí kódu, který je uveden v následujícím příkladu, můžete určit, zda je instance typu s možnou hodnotou null:

int? a = 14;
Console.WriteLine(IsOfNullableType(a));  // output: True

int b = 17;
Console.WriteLine(IsOfNullableType(b));  // output: False

bool IsOfNullableType<T>(T o)
{
    var type = typeof(T);
    return Nullable.GetUnderlyingType(type) != null;
}

Poznámka

Metody popsané v této části nelze použít v případě odkazových typů s možnou hodnotou null.

specifikace jazyka C#

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

Viz také