Archiv des Tags ‘C#2008’

C#2008 Sprachfeatures Teil 2: Automatische Properties

Freitag, den 25. Januar 2008

Ihr kennt sicherlich das mühsame Erstellen und Tippen von Properties für reine Datenhaltungsklassen. Will man unter C#2005 ein Property in einer Klasse modellieren, so muss man eine private Membervariable und ein zugehöriges Property mit Getter und Setter implementieren. Dies sieht dann in etwas so aus:

   private string _myProperty;

   public string MyProperty {
      get { return this._myProperty; }
      set { this._myProperty = value; }
   }

Man kann sich vorstellen, dass dieser Prozess bei Klassen mit mehreren Properties sehr umständlich ist! In C#2008 gibt es jetzt aber automatische Properties. Das obige Codesegment kann in C#2008 folgendermassen ausgedrückt werden:

   public string MyProperty { get; set; }

Wie man dem obigen Codeausschnitt entnehmen kann, muss man nur den Accesmodifier, den darunterliegenden Datentyp, den Propertynamen und einen leeren Get und Set Teil erstellen. Zur Kompilierzeit wird dem Property ein privates Feld und eine dazugehörige Implementation hinzugefügt (dies alles unter der Haube).

Einschränkungen
Es ist nicht möglich read-only oder write-only Properties zu definieren. Also folgende Codesegmente sind nicht erlaubt:

   public string MyProperty { get; }

oder

   public string MyProperty { set; }

Ebenfalls ist es nicht möglich in einer Klasse die ein automatisches Property deklariert auf die darunterliegende private Membervariable zu zugreifen, da das Feld ja erst zur Kompilierzeit quasi “induziert” wird. Die Klasse selber muss also immer die Propertysyntax brauchen. Z.B.

class MyExampleClass{
   public string MyProperty { get; }

   public override string ToString() {
      return string.Format("Tracelight.ch rocks! {0}", MyProperty);
   }
}

Eine weitere Einschränkung liegt darin, dass die automatischen Properties immer den Defaultwert des darunterliegenden Datentypes haben und nicht auf einen anderen Defaultwert initialisiert werden können. D.h. Referenzen sind immer null während z.B. Integer den Wert 0 haben usw. Will man den Properties beim Erstellen der Klasse einen Wert zuweisen, so muss dies über den Konstruktor der Klasse geschehen. Folgendes Beispiel demonstriert dies:

class MyClass {
   public string MyProperty { set; get; }

   public MyClass(string mypropValue) {
      MyProperty = mypropValue;
   }
}

Zugriff einschränken
Es ist möglich auch bei automatischen Properties dem Getter und Setter unterschiedliche Accessmodifier zu geben. Folgendes Codesegment sei gegeben:

   private string _myprop;

   public string MyProperty {
      get { return _myprop; }
      protected set { _myprop = value; }
   }

Dies kann unter C#2008 folgendermassen dargestellt werden:

   public string MyProperty { get; protected set; }

Somit ist es also nur aus ableitenden Klassen das Property MyProperty zu setzen.

Viel Spass

C#2008 Sprachfeatures Teil 1: Typisierte lokale Variablen

Montag, den 21. Januar 2008

Heute möchte ich euch die neuen typisierten lokalen Variablen von C#2008 etwas näher bringen. Typisierte lokale Variablen können in der neuen C# Spezifikation nun implizit angegeben werden durch das Keyword var.

In der C#2005 oder C#2.0 Spezifikation musste man noch lokale Variablen gemäss dem untenstehenden Codeausschnitt deklarieren:

   private void MyMethod() {
         int myLocalInt = 0;
         int myLocalBool = false;
   }

Neu ist es möglich durch das Keyword var eine lokale Variable zu deklarieren und der Kompiler wird automatisch den darunterliegenden Datentyp auf Basis des Initialwertes benützen. D.h. der Kompiler erkennt im untenstehenden Codesegment z.B. false als Boolean und wird myLocalBool automatisch als Boolean definieren.

   private void MyMethod() {
         var myLocalInt = 0;
         var myLocalBool = false;
   }

Dies funktioniert sogar mit komplexeren Datentypen oder in Loops, wie das das untenstehende Codesegment zeigt:

   private void MyMethod() {
         var myLocalArray = new int[]{1,2,3,4};
         var myLocalComputers = new List();
         var myLocalMacBook = new MacBookPro();

         foreach(var comp in myLocalComputers) {
              Console.WriteLine("My treasure: {0}", comp);
         }
   }

Ebenfalls ist es möglich implizit typisierte lokale Arrays zu erstellen über folgende Syntax:

   private void MyMethod() {
         var a = new[] {1, 2, 3, 4}; // int array
         var b = new[] {1, 1.2, 1.6, 2.5}; // double array
         var c = new[] { new MacBookPro(), new MacBookPro()}; // macbook pro array
   }

Was man nicht kann

  • Mit var deklarierte lokale Variablen auf Null setzen.
     var myObj = null;
  • Variablen die mit var deklariert wurden keineWerte zuweisen.
     var myData;
  • Implizite Arraydeklaration mit Mischtypen.
     var d = new[] {1, "eins", false};
  • Implizite Nullabletypes.
    var? car = new Car():
  • Deklaration von Feldern in Klassen mit var

Oh nein sind wir jetzt im Skriptingzeitalter?
Soweit kann ich euch beruhigen: Implizit typisierte Daten sind streng typisierten Daten! Das heisst es kann nicht wie bei einschlägigen Skriptsprachen ein anderer Wert einer lokal typisierten Variable zugewiesen werden! D.h. ein Typ

   var myInt = 0;

Kann nicht im späteren Verlauf anderen Datentypen zugewiesen werden. Dies wird vom Kompiler sichergestellt.

Warum soll ich das brauchen?
Naja ich denke man sollte dieses Feature so wenig wie möglich brauchen. Denn falls man später den eigenen Code für Bugfixing wieder heranziehen muss, kann es ganz schön verwirrend sein den entsprechenden Datentyp herauszufinden. Umso schwieriger wird es wenn man den Code eines Kollegen analysieren muss.

Das Keyword var hat vor allem seine Daseinsberechtigung im Umgang mit LINQ. Denn bei LINQ abfragen, weiss man nicht genau, was für ein Datentyp aus der Abfrage herausgeht. Dann deklariert man einfach einen Datentyp mit var und hat dann eine typisierte Variable die implizit durch die LINQ Abfrage definiert ist.