Donnerstag, 2. Juli 2009

back to basics: Nullable<T>

Der heutige btb-Post handelt soll sich etwas intensiver mit dem Thema "nullable value types" beschäftigen:

Das .NET-Framework unterscheidet zwischen 2 verschiedenen Arten von Typen - Wertetypen und Referenztypen. Während Referenztypen null werden, wenn ihnen kein Objekt zugewiesen wurde, haben Wertetypen diese Fähigkeit nicht. Diese werden bei ihrer Initialisierung direkt mit einem Wert belegt - false bei System.Boolean oder 0 bei System.Int32. Besonders bei der Arbeit mit Datenbanken - wo ein NULL (oder in .NET-Sprache DBNull) für einen nicht gesetzen Wert bei jeder Art von Typ exisitiert, kamen Entwickler immer wieder in Schwierigkeiten: Welcher Wert soll Null repräsentieren - ist es der Standard- der Minimal- oder der Maximalwert? Und was ist wenn dieser Wert mal wirklich ein gültiger Wert ist? Es ist also durchaus notwendig zwischen "0 weil nicht gesetzt" und "0 weil 0 gesetzt wurde" zu unterscheiden. Aus dieser Notwendigkeit heraus wurde die Struktur Nullable<T> geboren. Diese Struktur kann den zugrundeliegenden Wertetypen und ebenso auch Null-Werte beinhalten. Zur Arbeit mit dieser Struktur stehen 2 grundlegende Eigenschaften zur Verfügung: HasValue gibt zurück, ob ein Wert gesetzt wurde (true) oder ob null gespeichert ist (false); Value gibt den gespeicherten Wert zurück oder wirft eine InvalidOperationException, falls versucht wird auf Value zuzugreifen und null vorliegt.

Die Deklaration ist recht einfach - entweder man deklariert eine Nullable<T>-Struktur oder man verwendet den ?-Zugriffsmodifizierer:
Nullable<int> a;
int? b;

Ebenso einfach ist der Umgang mit Nullable<T>:
int? a = null;
if (a.HasValue)
{
 Console.WriteLine("Wert: {0}", a.Value);
}
else
{
 Console.WriteLine("kein Wert");
}

Natürlich können auch direkte Vergleiche mit null durchgeführt werden:
bool? a = null;
// returns the value of a or false if set to null
bool b = (a ?? false);
// returns whether a is null or not
bool c = (a == null);

Kick It on dotnet-kicks.de