Udostępnij przez


Typy wartości dopuszczalnych wartości (odwołanie w C#)

TypT? wartości dopuszczanej do wartości null reprezentuje wszystkie wartości bazowego typuT wartości i dodatkową wartość null. Można na przykład przypisać dowolną z następujących trzech wartości do zmiennejbool?: true, lub falsenull. Typ wartości T bazowej nie może być typem wartości dopuszczanej do wartości null.

Dokumentacja języka C# zawiera ostatnio wydaną wersję języka C#. Zawiera również początkową dokumentację funkcji w publicznej wersji zapoznawczej nadchodzącej wersji językowej.

Dokumentacja identyfikuje dowolną funkcję po raz pierwszy wprowadzoną w ostatnich trzech wersjach języka lub w bieżącej publicznej wersji zapoznawczej.

Wskazówka

Aby dowiedzieć się, kiedy funkcja została po raz pierwszy wprowadzona w języku C#, zapoznaj się z artykułem dotyczącym historii wersji języka C#.

Każdy typ wartości dopuszczanej do wartości null jest wystąpieniem struktury ogólnej System.Nullable<T> . Można odwołać się do typu wartości dopuszczanej wartości null z typem T bazowym w dowolnej z następujących zamiennych form: Nullable<T> lub T?.

Zazwyczaj należy użyć typu wartości dopuszczanej do wartości null, jeśli musisz reprezentować niezdefiniowaną wartość bazowego typu wartości. Na przykład zmienna logiczna lub bool, może mieć wartość lub truefalse. Jednak w niektórych aplikacjach wartość zmiennej może być niezdefiniowana lub brakująca. Na przykład pole bazy danych może zawierać true wartość lub false, lub może nie zawierać żadnej wartości, czyli NULL. Możesz użyć typu w tym scenariuszu bool? .

Deklaracja i przypisanie

Ponieważ typ wartości jest niejawnie konwertowany do odpowiedniego typu wartości dopuszczających wartość null, można przypisać wartość do zmiennej typu wartości dopuszczanej do wartości null, tak jak w przypadku jego bazowego typu wartości. Możesz również przypisać null wartość. Na przykład:

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

Wartość domyślna typu wartości dopuszczanej do wartości null reprezentuje nullwartość . Jest to wystąpienie, którego Nullable<T>.HasValue właściwość zwraca wartość false.

Badanie wystąpienia typu wartości dopuszczanej do wartości null

Aby sprawdzić wystąpienie typu null wartości dopuszczanej do wartości null i uzyskać wartość typu bazowego, użyj is operatora ze wzorcem 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

Zawsze można użyć następujących właściwości tylko do odczytu, aby sprawdzić i uzyskać wartość zmiennej typu wartości dopuszczanej do wartości null:

W poniższym przykładzie użyto HasValue właściwości , aby sprawdzić, czy zmienna zawiera wartość przed jej wyświetleniem:

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

Można również porównać zmienną typu wartości dopuszczanej z wartością null null zamiast używać HasValue właściwości, jak pokazano w poniższym przykładzie:

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

Konwersja z typu wartości dopuszczanej do wartości null do typu bazowego

Jeśli chcesz przypisać wartość typu wartości dopuszczanej do wartości null do zmiennej typu wartości innej niż null, może być konieczne określenie wartości, która ma zostać przypisana zamiast null. Użyj operatora ??łączenia wartości null, aby to zrobić. Możesz również użyć Nullable<T>.GetValueOrDefault(T) metody w tym samym celu:

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

Jeśli chcesz użyć wartości domyślnej bazowego typu wartości zamiast null, użyj Nullable<T>.GetValueOrDefault() metody .

Można również jawnie rzutować typ wartości dopuszczanej do wartości null do typu innego niż null, jak pokazano w poniższym przykładzie:

int? n = null;

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

W czasie wykonywania, jeśli wartość typu wartości dopuszczanej do wartości null to null, jawne rzutowanie zgłasza wartość InvalidOperationException.

Typ T wartości innej niż null jest niejawnie konwertowany na odpowiadający typ T?wartości dopuszczanej do wartości null.

Operatory zniesione

Typ T? wartości dopuszczający wartość null obsługuje wstępnie zdefiniowane operatory jednoargumentowe i binarne lub wszelkie przeciążone operatory obsługiwane przez typ T wartości. Te operatory, znane również jako operatory zniesione, zwracają wartość null , jeśli jeden lub oba operandy to null. W przeciwnym razie operator używa zawartych wartości operandów, aby obliczyć wynik. Na przykład:

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

Uwaga

bool? Dla typu wstępnie zdefiniowane & operatory i | nie są zgodne z regułami opisanymi w tej sekcji: wynik oceny operatora może być inny niż null, nawet jeśli jeden z operandów to null. Aby uzyskać więcej informacji, zobacz sekcję Operatory logiczne dopuszczane do wartości null w artykule Logiczne operatory logiczne.

W przypadku operatorów< porównania, >, <=i >=, jeśli jeden lub oba operandy to null, wynikiem jest false. W przeciwnym razie porównywane są zawarte wartości operandów. Nie zakładaj, że ponieważ określone porównanie (na przykład ) zwraca falsewartość , odwrotne porównanie (>) zwraca wartość true. <= W poniższym przykładzie pokazano, że 10 to

  • ani większe niż, ani równe null
  • lub mniej niż 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

W przypadku operatora== równości, jeśli oba operandy to null, wynikiem jest true. Jeśli tylko jeden z operandów to null, wynik to false. W przeciwnym razie porównywane są zawarte wartości operandów.

W przypadku operatora!= nierówności, jeśli oba operandy to null, wynik to false. Jeśli tylko jeden z operandów to null, wynik to true. W przeciwnym razie porównywane są zawarte wartości operandów.

Jeśli istnieje konwersja zdefiniowana przez użytkownika między dwoma typami wartości, można również użyć tej samej konwersji między odpowiadającymi typami wartości null.

Boxing and unboxing (Boks i rozpakowywanie)

Podczas pola wystąpienia typu T?wartości dopuszczanej do wartości null obowiązują następujące reguły:

  • Jeśli HasValue zwraca falsewartość , operacja boxing zwraca odwołanie o wartości null.
  • Jeśli HasValue zwraca truewartość , operacja boksu pola odpowiadającej mu wartości typu Twartości bazowej, a nie wystąpienia Nullable<T>klasy .

Możesz rozpakować pole typu wartości typu wartości T do odpowiedniego typu T?wartości dopuszczanej do wartości null, jak pokazano w poniższym przykładzie:

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 zidentyfikować typ wartości dopuszczanej do wartości null

W poniższym przykładzie pokazano, jak określić, czy System.Type wystąpienie reprezentuje skonstruowany typ wartości dopuszczający wartość null, System.Nullable<T> czyli typ z określonym 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 pokazano w przykładzie, użyj operatora typeof , aby utworzyć System.Type wystąpienie.

Jeśli chcesz określić, czy wystąpienie ma typ wartości dopuszczającej wartość null, nie używaj Object.GetType metody , aby uzyskać Type wystąpienie do testowania przy użyciu poprzedniego kodu. Po wywołaniu Object.GetType metody w wystąpieniu typu wartości dopuszczanej wartości null wystąpienie jest w poluObject. Ponieważ boxing wystąpienia wartości innej niż null typu wartości dopuszczającej wartość null jest równoważne poleceniu wartości bazowego typu, GetType zwraca Type wystąpienie reprezentujące podstawowy typ wartości null:

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

Ponadto nie używaj operatora is , aby określić, czy wystąpienie ma typ wartości dopuszczalnej wartości null. Jak pokazano w poniższym przykładzie, nie można odróżnić typów wystąpienia typu wartości null i jego wystąpienia typu bazowego is przy użyciu operatora :

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?

Zamiast tego użyj Nullable.GetUnderlyingType metody z pierwszego przykładu i operatora typeof , aby sprawdzić, czy wystąpienie ma typ wartości dopuszczalnej wartości null.

Uwaga

Metody opisane w tej sekcji nie mają zastosowania do typów odwołań dopuszczanych do wartości null.

specyfikacja języka C#

Aby uzyskać więcej informacji, zobacz następujące sekcje specyfikacji języka C#:

Zobacz też