C# 9.0 bringt prägnante, unveränderbare Typen

Seite 3: Target-Typed New Expression

Inhaltsverzeichnis

Unter dem sperrigen Namen "Target-Typed New Expression" verbirgt sich in C# 9.0 die Möglichkeit, Instanzierungen von Typen prägnanter zu schreiben als bisher. Ursprünglich erfolgte in C# eine Deklaration mit gleichzeitiger Instanziierung immer mit doppelter Nennung des Typnamens:

Person p = new Person(123, "Schwichtenberg", "Holger");

Seit C# 3.0 ist es durch Verwendung des Schlüsselwortes var vor dem Variablennamen den Instanzierungsausdruck zu verkürzen:

var p = new Person(123, "Holger", "Schwichtenberg");

Das führt aber auch heute noch zu vielen Diskussionen in Entwicklungsteams, weil viele Entwickler diese Syntax fälschlicherweise mit "Variant" in Visual Basic assoziieren.

Seit C# 9.0 bietet Microsoft in der Sprachsyntax eine andere Verkürzung an, die das Potenzial hat, weniger umstritten zu sein. Man kann nun nach dem Operator new den Klassennamen weglassen, wenn man Deklaration und Initialisierung in eine Zeile schreibt und der Typ instanziiert wird, der durch die Deklaration vorgegeben wurde. Voraussetzung ist natürlich, dass man die Klasse instanziieren will, die der Deklaration entspricht, und nicht etwa eine abgeleitete Klasse. Entwickler können also nun schreiben:

Person hs = new(123, "Holger", "Schwichtenberg");

Im Gegensatz zu var kann man Target-Typed New Expression auch in Klassenmitgliedern, zum Beispiel bei der Initialisierung von Properties und Fields einsetzen:

class Person
{
public int ID { get; init; }
public string Firstname { get; set; }
public string Surname { get; set; }
public Adresse Adresse { get; set; } = new();

}

Auch im Programmablauf kann man Datenmitglieder (Properties und Fields) ab C# 9.0 durch new() ohne Angabe des Klassennamens befüllen, da der Klassenname ja durch die Deklaration bereits feststeht:

Person p = new() { Vorname = "Holger", Nachname = "Schwichtenberg" };
p.Adresse = new() { Ort = "Essen", Land = "DE" };

Auch eine Übergabe als Methodenparameter ist möglich:

public void Umziehen(Adresse adresse)
{
this.Adresse = adresse;
}

p.Umziehen(new() { Ort = "Essen", Land = "DE" });

Diese letzten hier gezeigten Anwendungsgebiete haben wieder das Potenzial zu Diskussionen in den Entwicklungsteams, denn man sieht dabei ja nicht auf den ersten Blick, welche Klasse hier instanziiert wird.

Pattern Matching ist der Oberbegriff für eine Reihe zusätzlicher Vergleichsoperationen, die Microsoft in C# 7.0 in die Sprache einbaut hat. Dieses Sprachfeature wurde von Microsoft in C# 9.0 weiter ausgebaut.

Mit dem Operator is können Entwickler seit C# 7.0 ein Objekt in einer auf System.Object deklarierten Variablen auf einen beliebigen .NET-Typ prüfen und bei erfolgreicher Prüfung in eine zweite Variable, die nach dem Typ anzugeben ist, konvertieren lassen:

object eingabe = 123;

if (eingabe is int zahl) { Console.WriteLine(zahl * 2); }
else { Console.WriteLine("Keine Zahl!"); }

Mit C# 9.0 ist auch ein Vergleich auf Ungleichheit mit is not möglich:

if (eingabe is not int zahl2) { Console.WriteLine("Keine Zahl!"); }

In C# 9.0 kann man Typvergleiche in switch-Anweisungen per Pattern Matching prägnant definieren, wenn der konkrete Wert nicht interessiert. Microsoft nennt das "Simplified Type Pattern".