Zum Erscheinen unseres neuen C# 4.0 – kurz & gut und weiteren C# 4.0 Titeln hat der Übersetzer Lars Schulten einmal die Neuerungen von C# 4.0 zusammengetragen:
Nachdem C# 3.0 die Arbeit mit Datenstrukturen zum Thema hatte, dreht sich bei C# 4.0 alles um die Interaktion mit dynamischen Programmiersprachen. Die Neuerungen scheinen zunächst weniger umfassend und tiefgreifend, sind auf andere Art aber ähnlich spektakulär. C# 3.0 öffnete die Sprache funktionalen und deklarativen Elementen, C# 4.0 öffnet sie dynamischen Elementen.
Die neuen Sprachfunktionen fallen in vier Kategorien:
• Dynamische Operationen
• Optionale und benannte Parameter
• Vereinfachung der COM-Interaktion
• Kovarianz und Kontravarianz generischer Typen
Dynamische Operationen stellen einen kleinen Paradigmenwechsel für C# dar. Sie lockern die strikte statische Typisierung der Sprache, um die Interaktion mit dynamischen Programmiersprachen und die Arbeit mit Datenquellen zu vereinfachen, die Objekte liefern, deren Typen zur Kompilierzeit nicht bekannt sind.
Die Integration dynamischer Elemente hat zwei Bestandteile, einen neuen statischen Typ, dynamic
, der dafür sorgt, dass die Prüfung und Auflösung der entsprechenden Operationen bis zur Laufzeit aufgeschoben wird, und einen neuen Namensraum, System.Dynamic, der Interfaces und Klassen für die Unterstützung dynamischer Aufrufe definiert. Den Typ dynamic
könnten Sie beispielsweise folgendermaßen nutzen:
dynamic d =“hello“; Console.WriteLine (d.ToUpper()); // liefert HELLO Console.WriteLine (d.Foo()); // Kompiliert, liefert zur Laufzeit // aber einen Fehler
Besonders nützlich sind dynamische Objekte in Situationen, in denen andernfalls komplizierter Reflection-Code erforderlich wäre. Das ist nicht nur bei der Interaktion mit dynamischen Programmiersprachen der Fall. Hatten Sie schon einmal das Bedürfnis, aus einer Methode ein anonymes Objekt zu liefern? Mit dynamic
ist das kein Problem mehr. Deklarieren Sie die entsprechende Methode als dynamic
:
dynamic GetDynamic() { return new { Text = "The answer" }; }
Vom Aufrufer könnte sie dann folgendermaßen eingesetzt werden:
dynamic dynObject = GetDynamic(); dynObject.Text
Optionale Parameter müssen beim Methodenaufruf nicht angegeben werden, weil bei der Methodendefinition bereits ein Standardwert vorgegeben wurde, der verwendet wird, wenn kein Wert für diesen Parameter übergeben wird, z.B.:
void do (String what, int times = 1) {...}
Benannte Parameter werden anhand des angegebenen Parameternamens zugeordnet, nicht anhand der Position der Parameter im Aufruf:
do (what : "Something", times : 3);
Gemeinsam vereinfachen optionale und benannte Parameter die Arbeit mit COM-APIs, die viele, teilweise optionale Parameter verlangen. Sie können außerdem eingesetzt werden, um Methodenüberladungen zu reduzieren, die nur dazu dienen, Methoden mit Standardargumenten aufzurufen. Neben den zuvor erläuterten allgemeinen nutzbaren Neuerungen gibt es einige neue Sprachfeatures, die spezifisch der Vereinfachung der COM-Interaktion dienen.
COM-APIs können so importiert werden, dass Variant-Typen als dynamic
geliefert werden. Es kann also direkt auf zurückgelieferte Objekte zugegriffen werden, ohne das Typumwandlungen erforderlich sind.ref
-Parameter können jetzt per Wert angegeben werden und werden transparent als Referenzen übergeben.
Kovarianz und Kontravarianz bereinigen eine gelegentlich der Intuition widerstrebende Eigenschaft generischer Typen. Vor C# 4.0 waren generische Typen generell nicht kovariant, da das die Typsicherheit verletzen könnte, z.B.:
List<string> ls = new List<string>(); List<object> lo = ls; // Kompilierte nicht, da dann lo.Add(1); // dies zulässig wäre.
Bei generischen Typen, bei denen Objekte des generischen Typs nur auf der Eingabeseite oder nur auf der Ausgabeseite verwendet werden, besteht diese Gefahr nicht. Ein IEnumerable<string> könnte sicher als IEnumerable<object> verwendet werden, ebenso umgekehrt ein IComparer<object> als IComparer<string>. In C# 4.0 wird das für Interfaces und Delegates möglich. Außerdem können eigene generische Interface- und Delegate-Typen so definiert werden, dass sie Kovarianz und/oder Kontravarianz unterstützen. In C# 4.0 können Sie jetzt also Folgendes machen:
List<string> ls = new List<string>(); IEnumerable<object> ieo = ls;
Dies ist ein Gastbeitrag von Lars Schulten. Er ist freier Übersetzer für IT-Fachliteratur und hat für den O’Reilly Verlag schon unzählige Bücher zu ungefähr allem übersetzt, was man mit Computern so anstellen kann. Eigentlich hat er mal Philosophie studiert, aber mit Computern schlägt er sich schon seit den Zeiten herum, da Windows laufen lernte. Die Liste der Dinge, mit denen er sich beschäftigt, ist ungefähr so lang, launenhaft und heterogen wie die seiner Lieblingsessen und Lieblingsbücher.