Mit dem .NET Framework 3.5 kommt auch eine neue Version von C#, welche viele Neuerungen für uns bereit hält. Zum einen kann der Quellcode wesentlich verkürzt werden ohne dabei unleserlich zu werden,und zum anderen werden völlig neue Möglichkeiten eröffnet. Dieser Artikel soll einen kurzen Überblick über diese Features geben. Ich hoffe sie sind ebenso begeistert wie ich.
Automatically Implemented Properties
Ich habe es schon immer etwas störend empfunden, wenn man zu vielen Variablen immer die Properties per Hand eingeben musste. Später war mir da der ReSharper eine große Hilfe. Doch jetzt wird die Sache, auch ohne, deutlich einfacher. So sah ein privates Feld mit zugehörigem Property bis jetzt aus:
private string _Message;
public string Message
{
get { return _Message; }
set { _Message = value; }
}
Zuerst muss man seine Variable anlegen und dann muss das Property dafür geschrieben werden. Dies kann jetzt wie folgt vereinfacht werden:
public string Message { get; set; }
Natürlich könnte man jetzt sagen, dass man dafür auch einfach ein öffentliches Feld nehmen könnte. Aber man kann den Zugriff natürlich einschränken:
public string Message { get; private set; }
So kann auf die Variable nur innerhalb der Klasse schreibend zugegriffen werden. Zu beachten ist hierbei, dass immer ein get und set angegeben werden muss.Eine Variable, die auch innerhalb der Klasse nur gelesen oder geschrieben werden kann macht ja auch nicht viel Sinn. Dafür gibt es ja zum Beispiel Konstanten.
Object und Collection initializers
Diverse Properties einer Klasse können nun direkt bei ihrer Initialisierung mit Werten gefüllt werden.
Das ganze sieht dann so aus:
Email mail = new Email(“hans@xyz.de”) { Message = “Hello World”, From = “john@doe.de” }
Bei einem parameterlosen Konstruktor, kann man sogar die runden Klammern weg lassen.
Email mail = new Email() { From = “john@doe.de”, recipient = “hans@xy.de” }
Zu beachten ist hierbei, dass nicht alle Felder gefüllt werden müssen. Diese erhalten dann ihren normalen Wert, der ihnen in der Klasse zugewiesen wird.
Jede Klasse die System.Collections.Generic.IEnumerable<T> implementiert kann von Collection initializers profitieren. Dabei können die Collections gleich bei ihrer Erzeugung mit Werten gefüllt werden.Dieses Feature kann man wie folgt verwenden:
List<Email> myEmail = new List<Email>
{
new Email(“1@zwei.de”),
new Email(“2@zwei.de”),
new Email(“3@zwei.de”),
new Email(“4@zwei.de”)
};
Bei der Ausführung wird dann zuerst die Liste initialisiert und dann werden per Add(…) die Elemente hinzugefügt. Dafür muss die Add Methode natürlich public sein.
Implicitly typed local Variables
In C# 3.0 kann der Datentyp einer Variablen vom Compiler implizit festgelegt werden. Dazu dient das Schlüsselwort var, welches bereits aus diversen Scriptsprachen bekannt sein dürfte. Doch anders als bei diesen, kann der Datentyp einer mit var deklarierten Variablen sich nicht während der Laufzeit des Programms ändern. Ihr wird der Typ bei ihrer initialisierung vom Compiler zugewiesen. Deshalb ist es auch notwendig die Variable bei ihrer Deklaration zu initialisieren. Dies sieht dann so aus:
var number = 27;// number ist vom Typ int
var message = „Hallo“// message ist vom Typ string
Wenn sie diese Zeilen im Visual Studio in einer Klasse schreiben, können sie mit der Maus über eine Variable gehen und werden im Quickinfo den entsprechenden Typ sehen. Wenn sie ein Array mit var deklarieren wollen, müssen sie zusätzlich new[] verwenden.
var numbers = new[] { 1, 2, 3};
Wozu soll das nun gut sein? Mit Hilfe von var lässt sich wesentlich generischer Code schreiben. Egal was die Methode GetSomeData() im folgenden Beispiel liefert, in der foreach Schleife kann immer ihr Inhalt ausgegeben werden.
var dataList = GetSomeData();
foreach( var data in dataList)
Console.WriteLine(data);
Außerdem kommt var bei LINQ exzessiv zur Verwendung. Doch dazu später mehr.
Extension Methods
Extension Methods sind meiner Meinung nach, eine der ganz besonders praktischen Neuerungen in C# 3.0. Mit ihnen lassen sich Klassen um Methoden erweitern, ohne dass man die Klasse selbst ändern muss. Man muss also nicht einmal Zugriff auf den Quellcode der Klasse habe oder diese neu übersetzen. Konkret bedeutet das, dass man auch Klassen irgendeines Frameworks erweitern kann. Die Extension Method muss dazu in einer statischen Klasse als statische Methode deklariert werden. Außerdem muss der erste Parameter vom Typ der zu erweiternden Klasse sein und dem Schlüsselwort this folgen.
public static class ExtensionMethods
{
publicstatic bool IsSpam( this Email mail, List<string> blackList)
{
return blacklist.Contains(mail.Sender);
}
}
An einer anderen Stelle, kann dann diese Methode auf den Typ Email aufgerufen werden.
public static void Main(string[] args)
{
…
List<string> blackList = GetBlackList();
Email mail = GetNewMail();
If (mail.IsSpam(blackList))
mail.Delete();
…
}
Wichtig ist noch, dass die Extension Method nur zur Verfügung steht, wenn ihr Namespace inkludiert wurde.
Lambda Expressions
In C# 2.0 wurden anonyme Methoden eingeführt, die es erlauben Delegates, gleich bei ihrer Initialisierung mit einem Funktionsrumpf zu versehen. Das war und ist sehr praktisch, wenn man, zum Beispiel, in einer Liste nach einem bestimmten Element sucht.Lambda Expressions bieten nun eine wesentlich einfachere Syntax. Stellen sie sich zum Beispiel vor, sie suchen alle Emails von Hans@Maulswurf.de aus einer Liste von Emails.
var mail = mailList.FindAll(m => m.Sender == „Hans@Maulswurf.de“)
Eine Lambda Expression besteht aus einer Parameterliste, dem Zeichen => und einem Ausdruck. Dabei können die Typen der Parameterliste explizit oder implizit angegeben werden. Zur Suche der Emails hätten wir also auch folgendes schreiben können.
var mail = mailList.FindAll( (Email m) => m.Sender == „Hans@Maulswurf.de“)
Lamda Expressions werden sehr häufig bei der Verwendung von LINQ eingesetzt. Dazu soll aber noch ein extra Artikel folgen.