Kolumne: C# im Fokus

Effiziente Datentypkonvertierung mit C
Kommentare

Im vorherigen Teil der C#-Kolumne wurden die wesentlichen Methoden der Datentypkonvertierung erläutert. Es wurde gezeigt, dass je nach .NET-Version mehrere Möglichkeiten zur Verfügung stehen. Im heutigen Artikel wird der Frage nachgegangen, in welcher Situation ein bestimmter Konvertierungsmechanismus am geeignetsten ist.

Konvertierungsvorgänge gehören neben Schleifen und Bedingungen zu den meistverwendeten Sprachkonstrukten innerhalb einer strukturierten Programmiersprache wie C#. Würde nur ein Mechanismus dazu zur Verfügung stehen, wäre auch alles sehr einfach. Aber wie so oft existieren mehrere Alternativen gemäß dem Motto: Wer die Wahl hat, hat die Qual. In der letzten C#-Kolumne wurden die folgenden Möglichkeiten der Konvertierung erläutert:

  • Parse und TryParse
  • Typumwandlung per Cast-Operation
  • as-Operator
  • Convert-Klasse

Zusätzlich finden teilweise auch implizite Konvertierungen statt, die ohne Zutun des Entwicklers vom Compiler automatisch durchgeführt werden. Jetzt stellt sich natürlich die Frage, wann welche Methode zur Typumwandlung verwendet werden kann bzw. am effizientesten ist. In den folgenden Abschnitten werden die Besonderheiten der einzelnen Methoden vorgestellt. Am Ende werden die verschiedenen Möglichkeiten gegenübergestellt. 

Cast vs. as

Mittels einer Cast-Operation können sowohl Referenz- als auch Wertetypen umgewandelt werden. Der as-Operator ist dagegen nur in der Lage, zwischen Referenztypen zu konvertieren. Das Einsatzgebiet des as-Operators ist daher auf die Konvertierung von Referenztypen beschränkt. Referenztypen können aber auch per Cast-Operation konvertiert werden. Hierbei kommt die alte C-Syntax zum Einsatz und der gewünschte Zieldatentyp wird der Quellvariablen vorangestellt: ObjectA newType = (ObjectA)targetObj. Wenn der Cast-Vorgang erfolgreich abgeschlossen wurde, kann ohne Probleme auf die Variable newType zugegriffen werden. Ist der gewünschte Zieldatentyp allerdings nicht kompatibel, kommt es zu einer InvalidCastOperation-Exception. Der as-Operator dagegen wirft keine Ausnahme (Exception), wenn eine Konvertierung ungültig ist, stattdessen wird ein Nullobjekt zurückgegeben. Beide Operatoren nehmen dem Entwickler nicht Kontrolle ab, ob der Konvertierungsprozess erfolgreich durchgeführt wurde. Der Cast-Vorgang eignet sich gut, wenn die Wahrscheinlichkeit einer Typunverträglichkeit (fast) ausgeschlossen werden kann. In vielen Fällen kann dieser Fehler auch nicht vernünftig behandelt werden und die InvalidCastOperationException wird zunächst nicht weiter behandelt. Der Hinweis der ungültigen Typumwandlung ist eher für die Fehleranalyse hilfreich. Setzt man für diesen Vorgang den as-Operator ein, wird zunächst keine Ausnahme (Exception) geworfen. Wird dann ohne weitere Kontrolle auf die Variable zugegriffen, kommt es lediglich zu einer – mehr oder weniger aussagekräftigen – NullReferenceException. Das Listing 1 zeigt dazu ein entsprechendes Beispiel. Implementiert wurden zwei Methoden, die jeweils einen Parameter vom Typ object erwarten. Innerhalb der Methoden wird der übergebene Typ auf einen string-Typ konvertiert. Wird die Methode MethodA mit einem Integer-Wert aufgerufen, wird – wie erwartet – eine InvalidCastOperationException ausgelöst. Bei dem gleichen Aufruf der Methode MethodB kommt es lediglich zu einer allgemeinen NullReferenceException. Je nachdem, wann auf die Variable zugegriffen wird, kann die Ausnahme erst viel später ausgelöst werden und die Fehleranalyse wird erschwert. Der as-Operator eignet sich für Einsatzfälle, wenn die Wahrscheinlichkeit einer Typunverträglichkeit hoch ist und der Fehler nicht zwingend zu einem Programmabbruch führt. Die Implementierung der Equals-Methode, die jede Klasse implementieren sollte, ist dafür ein gutes Beispiel. Der Methode kann ein beliebiges Objekt zum Vergleich übergeben werden. Die Methode vergleicht die übergebene Objektinstanz mit sich selbst und signalisiert über den Rückgabewert, ob die Objekte gleich sind oder nicht. Das Listing 2 zeigt dazu eine beispielhafte Implementierung mittels Cast und dem as-Operator. Wie anhand der beiden Methodenimplementierungen zu erkennen ist, ergibt sich bei dem Einsatz des as-Operators – in diesem Kontext – auch eine überschaubarere Implementierung gegenüber dem Cast-Operator.

Listing 1

public static void MethodA(object param)
{
  string name = (string)param;
  Console.WriteLine("Der Wert der Variablen lautet: {0}", name.ToString());
}
public static void MethodB(object param)
{
  string name = param as string;
  Console.WriteLine("Der Wert der Variablen lautet: {0}", name.ToString());
}  

Listing 2

public override bool Equals(object compare)
{
  if (compare == null)
    return false;
  if (!(compare is Person))
    return false;
  Person person = (Person)compare;
  // Comparing ...
  return true;
}
public override bool Equals(object compare)
{
  Person person = compare as Person;
  if (compare == null)
    return false;
  // Comparing ...
  return true;
}  
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -