Kolumne: C# im Fokus

Flexibles Typsystem in C
Kommentare

Die Zuweisung von Typen wird vom Compiler überwacht und somit auch eingeschränkt. Dadurch können im Vorfeld fehlerhafte Typzuweisungen während der Übersetzungszeit frühzeitig erkannt und gelöst werden. Die Art und Weise der Prüfung und das Verhalten sind allerdings abhängig von der verwendeten C#-Version.

Bevor im Detail auf die Begriffe „Covariance“ und „Contravariance“ eingegangen wird, sollen sie zunächst allgemein erläutert werden. Im Kontext einer Programmiersprache beziehen sich die beiden Ausdrücke Covariance und Contravariance auf die Reihenfolge von Typen. Mit Reihenfolge ist hier die Beziehung zwischen kleinerem und erweitertem Typen gemeint. Wobei der Begriff „kleinerer Typ“ nicht zwangsweise bedeutet, dass es sich um einen abgeleiteten Typen handeln muss. Weiterhin beschreiben die beiden Begriffe die Austauschbarkeit bzw. Gleichwertigkeit von Typen in bestimmten Situationen. Findet eine implizite Typkonvertierung von einem erweiterten zu einem kleineren Typen statt, handelt es sich um ein covariantes Verhalten. Im umgekehrten Fall spricht man von einem contravarianten Verhalten. Ist keine Konvertierung möglich, handelt es sich um ein invariantes Verhalten.

Beziehungen zwischen Typen

Durch die erweiterte Typkonvertierung in C# ermöglichen Covariance und Contravariance die implizite Typkonvertierung von Arrays, Schnittstellen, Delegates und generischen Typen. Betrachtet man zwei Typen namens A und B, dann trifft genau eine der folgenden Aussagen immer zu: A ist größer als B, A ist kleiner als B, A ist gleich B oder A und B sind unterschiedlich. In C# werden diese Regeln ausgewertet, um sichere Typzuweisungen zu ermöglichen. C# erlaubt dabei die Zuweisung kompatibler Typen und setzt damit das so genannte Substitutionsprinzip (Substitution Principle) um. Das bedeutet, dass ein speziellerer Typ (Subtype) einem mehr generischen Typ zugewiesen werden kann (Listing 1). Definiert wurde zunächst eine einfache Klassenhierarchie. Die Klasse Binary stellt dabei die absolute Basisklasse dar. Abbildung 1 verdeutlicht die Beziehungen der einzelnen Klassen anhand eines Klassendiagramms. Wie in Listing 1 erkennbar ist, kann eine Variable vom Typ Binary alle Instanzen aufnehmen, die gleich oder kleiner der Binary-Klasse sind. Außerdem stellt man fest, dass eine umgekehrte Zuweisung nicht möglich ist. Bei diesem Versuch meldet der Compiler folgenden Fehler: Cannot implicitly convert type Binary to CPlusPlus. An explicit conversion exists (are you missing a cast?). Da der Typ CPlusPlus ein kleinerer bzw. spezialisierter Typ ist, kann er nicht automatisch in den mehr generischen Typ Binary umgewandelt werden.

Listing 1

public static void Listing1()
{
  Binary bin = new Binary();
  Assembler assembler = new Assembler();
  C c = new C();
  Pascal pascal = new Pascal();
  CPlusPlus cplusplus = new CPlusPlus();

  bin = assembler;
  bin = c;
  bin = pascal;
  bin = pascal;
  bin = cplusplus;      
}  
Abb. 1: Klassendiagramm
Abb. 1: Klassendiagramm
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -