Zum Inhalt springen
Tags

, ,

C# vNext – Primary Constructors und Property Intializers

September 30, 2014

C# 6 bringt zahlreiche neue Features in der Sprache. Dieser Artikel beschreibt Primary Constructors und wie sie Code ändern können.

Update: Primary Constructors kommen jetzt definitiv nicht in C# 6. Vielleicht in C# 7. Info: https://roslyn.codeplex.com/discussions/568820

Sharp right
© Liquidphoto | Dreamstime.comSharp Right Turn Sign Photo

Neue Features in C#: mit C# 2 sind generics neu gekommen, C# 3 brachte zahlreiche Syntaxerweiterungen für Language Integrated Query (LINQ) und hat fast jede (oder jede) Applikation beeinflusst. Die Neuigkeiten bei C# 4 waren dann bei einigen Szenarien wie der Integration von Scripting oder auch COM praktisch. Mit Version 5 gab es dann zwar nur zwei neue Keywords, die waren aber so wichtig und haben die asynchrone Programmierung vereinfacht dass sie wieder praktisch jedes Programm beeinflussten.

Version 6 bringt jetzt keine so wichtige Features wie wir das bei den Neuerungen der Vorgängerversion erleben durften. Aber dafür gibt es viele praktische Dinge. Da legen wir gleich mit Primary Constructors los.

Ein praktischer Anwendungsfall für Primary Constructors sind immutable Typen. Readonly Properties waren in der letzten Version von C# nicht mit auto properties möglich. Da musste es der gesamte Syntax sein um die Properties zu definieren, wie in der Klasse Gadget gezeigt.

public class Gadget
{
  public Gadget(int id, string name)
  {
    this.id = id;
    this.name = name;
  }

  private readonly int id;
  public int Id
  {
    get { return id; }
  }

  private readonly string name;
  public string Name
  {
    get { return name; }
  }

  public override string ToString()
  {
    return Name;
  }
}

Oft hat man sich in solchen Szenarien mit private set accessors beholfen, das ist mit automatic properties möglich:


public string Name { get; private set; }

Mit dem private set accessor kann diese Property nur in der Klasse selbst geändert werden. Der State ist aber nicht immutable. Änderungen sind jederzeit möglich.

Property Initializers

C# 6 erlaubt jetzt Property Initializers um eine Property gleich mit dem Erzeugen des Objektes zu initialisieren:


public string Name { get; set; } = "Sample";

Das ist jetzt auch nur mit einem get Accessor möglich. Dabei wird vom Compiler ein readonly field erzeugt.


public string Name { get; } = "Sample";

Beim Initializer ist es nicht möglich auf “this” zuzugreifen. Damit sind die Anwendungsszenarien hier doch sehr eingeschränkt – wäre nicht der Primary Constructor.

Primary Constructors

Der Primary Constructor wird direkt bei der Klasse definiert. Die Constructor-Parameter können dann direkt beim Property Initializer angegeben werden. Der Code der Gadget Klasse von vorhin wird damit sehr reduziert:

public class Gadget(int id, string name)
{
  public int Id { get; } = id;
  public string Name { get; } = name;

  public override string ToString()
  {
    return Name;
  }
}

Im Vergleich zu vorher ist die Klasse Gadget viel kürzer geworden. Nur die ToString Methode hat nichts an der Länge eingebüßt. Das wird sich aber noch in einem folgenden Blogartikel ändern.

Wie sieht es mit Primary Constructors jetzt aus bei etwas spezielleren Anwendungsfällen? Aufruf von Basisklassen, mehreren Constructors, und Contructor Body Implementierungen?

Basisklassen

Natürlich ist es auch möglich vom Primary Constructor auf den Constructor der Basisklasse zu verweisen. Dazu erstelle ich zuerst eine Basisklasse Base die selbst einen Primary Constructor verwendet.

class Base(int i)
{
  public int I { get;  } = i;
}

Die Klasse Derived referenziert den Constructor der Basisklasse mit dem Integer Argument und setzt außerdem die S Property.

class Derived(string s, int i): Base(i)
{
  public string S { get; } = s;
}

Constructor Block

Sollte auch noch Code beim Aufruf des Primary Constructors aufgerufen werden ist das in einem Constructor Block möglich. Einfach geschwungene Klammern nach der Klassendeklaration schreiben:

class Derived(string s, int i): Base(i)
{
  {
    Console.WriteLine("Derived ctor called");
  }

  public string S { get; } = s;
}

Mehrere Constructors

Mehrere Constructors sind natürlich auch möglich. Ein weiterer Constructor kann über den Constructor Intiailizer den Primary Constructor aufrufen.

class Derived(string s, int i): Base(i)
{
  {
    Console.WriteLine("Derived ctor called");
  }

  public Derived(int i)
    : this(string.Empty, i)
  {
  }

  public string S { get; } = s;
}

Was hältst du von diesem neuen C# Feature? Wird es deinen Code vereinfachen? In meinen Projekten sehe ich auf jeden Fall viele Vereinfachungen. Vielleicht reduziert sich damit auch die Seitenanzahl von Professional C# 😉

Christian

CN innovation

One Comment

Trackbacks & Pingbacks

  1. C# vNext – Null Propagation | CN innovation

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit deinem WordPress.com-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s

%d Bloggern gefällt das: