Montag, 9. Juni 2008

Fallstrick: DateTime.AddXXX()

Ich stolpere immer wieder darüber und wie ich heute gesehen habe, bin ich tatsächlich nicht der einzige, dem es so geht:

Auf einen vorhandenen DateTime soll eine bestimmte Anzahl von Stunden (oder Minuten, Sekunden, ...) addiert werden. Natürlich, kein Problem, dafür bietet der DateTime ja die Methode AddHours(). Ein Aufruf, um auf das aktuelle Datum mit der aktuellen Uhrzeit fünf Stunden zu addieren, sähe demnach so aus:

   1:  DateTime dt = DateTime.Now;
   2:  dt.AddHours(5.0);

Verwendet man jetzt jedoch den Wert von dt weiter, um ihn beispielsweise anzuzeigen, fällt auf, dass die fünf Stunden nicht wie erwartet auf den aktuellen Wert addiert wurden. Der Grund hierfür ist ein ganz einfacher, der einem sogar von IntelliSense angezeigt wird.
Der Aufruf geht einfach deshalb ins Leere, weil er nicht auf den übergebenen DateTime addiert, sondern das Ergebnis der Addition zurück gibt. Irgendwo logisch, es handelt sich ja nicht um einen ref- oder out-Parameter, andererseits ist es dennoch irgendwie verwirrend, da es einfach logisch erscheint, dass auf den Ursprungswert addiert wird.

Wie auch immer, der korrekte Aufruf muss wie folgt aussehen:

   1:  DateTime dt = DateTime.Now;
   2:  dt = dt.AddHours(5.0);

Auf dass ich in Zukunft nicht mehr hierüber stolpern werde!

Vergleich VB.NET und C#

Ich springe in letzter Zeit öfter mal zwsichen VB.NET und C# hin und her, wobei ich ganz klar aus der C#-Ecke komme und mich daher mit der Syntax von VB.NET nicht wirklich auskenne.
Da kommt mir diese Seite mehr als gelegen. Hier wird ein direkter Vergleich angestellt, wie etwas in C# und VB.NET realisiert wird. Danke dafür an meinen Kollegen Sebastian.

Sollte ein Leser des Öfteren zwischen C# und Java wechseln müssen, für den gibt es hier eine ähnliche Übersicht.

Dienstag, 3. Juni 2008

Hashtable in Key Reihenfolge abarbeiten

Ich hatte in einer Hashtable Strings mit einem Integer Wert als Key abgelegt und wollte die nun in numerischer Folge abarbeiten, mein erster gedankenloser Ansatz war etwas umständlich. Mit etwas nachdenken hatte ich einen eleganteren Weg gefunden.

Dazu hab ich ersteinmal die Hashtable in ein generisches Dictionary umgewandelt, dann die Keys in eine generische Liste geschaufelt und dann einfach den Sort angewendet. Natürlich hätte dies auch mit einer Hashtable und einer Arraylist funktioniert, aber da beide in jeder Hinsicht in der Performance den Generics unterlegen sind hab ich das umgeschrieben nach diesem Beispiel:

   1:  ...
   2:  Dictionary<int, string> ht = new Dictionary<int, string>(10);
   3:  ht.Add(1, "hallo");
   4:  ht.Add(2, "welt");
   5:  ht.Add(3, "!");
   6:  ...
   7:             
   8:  List<int> keys = new List<int>(ht.Keys);
   9:  keys.Sort();
  10:   
  11:  foreach (int k in keys)
  12:  {
  13:     System.Console.WriteLine("key = " + k.ToString() + " value = " + (string)ht[k]);
  14:  }
  15:  ...

Das funktioniert dann auch analog mit anderen Datentypen, ggf. muss dann der Comparer implementiert/überladen werden, je nach Geschmack :)