Donnerstag, 10. April 2008

? unter C# und .NET 2.0

Jeder kennt - denke ich - den folgenden Ausdruck, der eine if/else Abfrage auf das Wesentliche komprimiert:

   1:  public void xyz(string save)
   2:  {
   3:      bool decide = save.ToLower() == "j" ? true : false;
   4:      ...
   5:  }

Ab .NET 2.0 geht aber noch mehr mit ?:

   1:  public void xyz(string save)
   2:  {
   3:      bool? decide = null;
   4:      ...
   5:  }

Huh? Eine null Zuweisung auf einen Value Type? Nein es ist ein Referenztyp in diesem Fall, da es sich der Generics unter 2.0 bedient, das in diesem Fall wie folgt definiert ist:

System.Nullable<t> wofür wiederum ein T? definiert wurde.

Das ist doch schon mal cool, aber wie stell ich fest ob es sich um einen Value oder Referenztyp handelt wenn ich einen solchen Wert zugeschoben bekomme?

   1:  int? i = 0;
   2:   
   3:  Type t1 = typeof(int?);    // System.Nullable...System.Int32
   4:  Type t2 = i.GetType();     // System.Int32
   5:   
   6:  bool eq = t1 == t2;        // false

Also das funktioniert offenbar schon einmal nicht! Und schlägt auch noch fehl, falls i == null gesetzt wurde.
Aber wir können uns folgendermaßen behelfen:

   1:  int x = i.HasValue ? (int)i : 0;

...und dafür gibt es gleich einen noch viel kürzeren neuen Ausdruck ab 2.0:

   1:  int x = i ?? 0;

Um den Generic zu bestimmen geht man wie folgt vor:

   1:  bool eq = t1.GetGenericTypeDefinition() == typeof(Nullable<>);

Doch Vorsicht! Wäre t1 nicht vom Type Generic, bekommen wir eine InvalidOperationException! Daher muß vorher noch abgeprüft werden ob es sich überhaupt um einen Generic handelt und da C# linksassoziativ auflöst, können wir das wie folgt zusammenstöpseln:

   1:  bool eq = t1.IsGenericType && t1.GetGenericTypeDefinition() == typeof(Nullable<>);

Keine Kommentare: