Verwenden von auf NULL festlegbaren Typen (C# Programmierhandbuch)

Aktualisiert: November 2007

Typen, die auf NULL festgelegt werden können, können alle Werte des zugrunde liegenden Typs und einen zusätzlichen null-Wert darstellen. Typen, die auf NULL festgelegt werden können, werden auf zwei verschiedene Arten deklariert:

System.Nullable<T> variable

-oder-

T? variable

T ist der zugrunde liegende Typ des auf NULL festlegbaren Typs. T kann ein beliebiger Werttyp einschließlich struct sein, aber kein Referenztyp.

Nehmen Sie als Beispiel für das Einsatzgebiet eines Typs, der auf NULL festgelegt werden kann, eine boolesche Variable. Sie kann zwei Werte annehmen: true und false. Es gibt keinen Wert, der "nicht definiert" angibt. In vielen Programmieranwendungen, besonders bei Datenbankinteraktionen, können Variablen in einem nicht definierten Zustand existieren. Ein Feld in einer Datenbank kann z. B. den Wert true oder false enthalten, aber es kann auch überhaupt keinen Wert enthalten. Auf ähnliche Weise können Referenztypen auf null festgelegt werden, um anzugeben, dass sie nicht initialisiert sind.

Diese Ungleichheit kann zu zusätzlichem Programmiereraufwand führen – beispielsweise zusätzliche Variablen zum Speichern von Zustandsinformationen, spezielle Werte usw. Der Modifizierer für Typen, die auf NULL festgelegt werden können, ermöglicht in C# das Erstellen von Werttypvariablen, die einen nicht definierten Wert angeben.

Beispiele von Typen, die auf NULL festgelegt werden können

Jeder Werttyp kann als Grundlage für einen Typ verwenden werden, der auf NULL festgelegt werden kann. Beispiel:

int? i = 10;
double? d1 = 3.14;
bool? flag = null;
char? letter = 'a';
int?[] arr = new int?[10];

Die Member der Typen, die auf NULL festgelegt werden können

Jede Instanz eines auf NULL festlegbaren Typs besitzt zwei öffentliche schreibgeschützte Eigenschaften:

  • HasValue

    HasValue ist vom Typ bool. Sie wird auf true festgelegt, wenn die Variable einen Wert ungleich NULL enthält.

  • Value

    Value hat denselben Typ wie der zugrunde liegende Typ. Wenn HasValue den Wert true hat, enthält Value einen sinnvollen Wert. Wenn HasValue den Wert false hat, löst das Zugreifen auf Value eine InvalidOperationException aus.

In diesem Beispiel wird mit dem HasValue-Member getestet, ob die Variable einen Wert enthält, bevor versucht wird, diese anzuzeigen.

int? x = 10;
if (x.HasValue)
{
    System.Console.WriteLine(x.Value);
}
else
{
    System.Console.WriteLine("Undefined");
}

Dieser Test kann auch wie in folgendem Beispiel ausgeführt werden:

int? y = 10;
if (y != null)
{
    System.Console.WriteLine(y.Value);
}
else
{
    System.Console.WriteLine("Undefined");
}

Explizite Konvertierungen

Ein auf NULL festlegbarer Typ kann in einen regulären Typ umgewandelt werden. Dies kann entweder explizit mit einer Umwandlung oder mit der Value-Eigenschaft erfolgen. Beispiel:

int? n = null;

//int m1 = n;      // Will not compile.
int m2 = (int)n;   // Compiles, but will create an exception if x is null.
int m3 = n.Value;  // Compiles, but will create an exception if x is null.

Wenn eine benutzerdefinierte Konvertierung zwischen zwei Datentypen festgelegt wird, kann dieselbe Konvertierung auch für auf NULL festlegbare Versionen dieser Datentypen verwendet werden.

Implizite Konvertierungen

Eine Variable eines auf NULL festlegbaren Typs kann mit dem Schlüsselwort null auf NULL festgelegt werden, wie im folgenden Beispiel gezeigt:

int? n1 = null;

Die Konvertierung von einem gewöhnlichen Typ in einen auf NULL festlegbaren Typ ist implizit.

int? n2;
n2 = 10;  // Implicit conversion.

Operatoren

Die vordefinierten unären und binären Operatoren sowie alle für Werttypen vorhandenen benutzerdefinierten Operatoren können auch von auf NULL festlegbaren Typen verwendet werden. Diese Operatoren generieren einen NULL-Wert, wenn die Operanden auf NULL festgelegt sind. Ansonsten verwendet der Operand den enthaltenen Wert, um das Ergebnis zu berechnen. Beispiel:

int? a = 10;
int? b = null;

a++;         // Increment by 1, now a is 11.
a = a * 10;  // Multiply by 10, now a is 110.
a = a + b;   // Add b, now a is null.

Wenn beim Vergleichen von Typen, die NULL-Werte zulassen, einer der Typen null ist, lautet das Ergebnis des Vergleichs immer false. Daher ist es nicht zulässig, aus einem Vergleich mit dem Ergebnis false abzuleiten, dass der entgegengesetzte Fall true ist. Beispiel:

int? num1 = 10;
int? num2 = null;
if (num1 >= num2)
{
    System.Console.WriteLine("num1 is greater than or equal to num1");
}
else
{
    // num1 is NOT less than num2
}

Die Schlussfolgerung in der obigen else-Anweisung ist nicht zulässig, da num2 gleich null ist und somit keinen Wert enthält.

Beim Vergleich von zwei Typen, die NULL-Werte zulassen und beide null sind, lautet das Ergebnis true.

Der ?? Operator

Der Operator ?? definiert einen Standardwert, der zurückgegeben wird, wenn ein auf NULL festlegbarer Typ einem Typ zugewiesen wird, der nicht auf NULL festgelegt werden kann.

int? c = null;

// d = c, unless c is null, in which case d = -1.
int d = c ?? -1;

Dieser Operator kann auch mit mehreren auf NULL festlegbaren Typen verwendet werden. Beispiel:

int? e = null;
int? f = null;

// g = e or f, unless e and f are both null, in which case g = -1.
int g = e ?? f ?? -1;

Der bool?-Typ

Der auf NULL festlegbare bool?-Typ kann drei verschiedene Werte enthalten: true, false und null. Weitere Informationen zur Umwandlung von einem bool?-Typ in einen bool-Typ finden Sie unter Gewusst wie: Sichere Umwandlung von bool? zu bool (C#-Programmierhandbuch).

Auf NULL festlegbare boolesche Typen entsprechen den in SQL verwendeten Variablen vom Typ Boolean. Um sicherzustellen, dass die mit den Operatoren & und | erzeugten Ergebnisse mit dem aus drei Werten bestehenden booleschen Typ in SQL übereinstimmen, werden die folgenden vordefinierten Operatoren bereitgestellt:

bool? operator &(bool? x, bool? y)

bool? operator |(bool? x, bool? y)

Die Ergebnisse dieser Operatoren sind in der folgenden Tabelle aufgeführt:

X

y

x&y

x|y

true

true

true

true

true

false

false

true

true

null

null

true

false

true

false

true

false

false

false

false

false

null

false

null

null

true

null

true

null

false

false

null

null

null

null

null

Siehe auch

Konzepte

C#-Programmierhandbuch

Referenz

Typen, die NULL-Werte zulassen (C#-Programmierhandbuch)

Boxing von Typen, die NULL-Werte zulassen (C#-Programmierhandbuch)