Neuerungen C# 3.0 |
|
---|---|
|
implizit getypte lokale VariablenIn C# kann man den Compiler entscheiden lassen, welchen Typ eine Variable
haben soll. Dazu lässt man bei der Deklaration den Typen weg und ersetzt
ihn durch das Schlüsselwort "
Bei diesem Konzept gibt es jedoch einige Restriktionen: Bei implizit getypten lokalen Arrays sehen die Deklarationen wie folgt aus:
Dabei muss darauf geachtet werden, dass alle Elemente im Initializer
kompatibel sind. Sollte man das explizit nicht wünschen (Strings und doubles),
muss das Array explizit als ErweiterungsmethodenEine Erweiterungsmethode ist eine statische Methode, die einer Klasse genau diese Methode hinzufügt, obwohl sie nicht in dieser deklariert wurde. Angenommen, es gibt eine Klasse
wobei diese Methode in einer anderen Klasse steht, die auch in einem anderen Namensraum liegen kann. Der Aufruf sähe dann wie folgt aus:
Sollte die Erweiterungsmethode in einem anderen Namensraum liegen, so muss
man diesen über die using-Klausel bekannt machen. Der Aufruf geschieht, wie oben gesehen, unter Auslassung des ersten mit
Man kann die Methode Wie man sich sicherlich denken kann, führt diese Art dazu, dass die Programme
sehr unstrukturiert und praktisch unwartbar werden und diese nur dann
eingesetzt werden sollten, wenn es gar keine andere Möglichkeit gibt.
Ich habe jedoch keinen zwingenden Grund gefunden, dieses Konzept einzusetzen.
Note
Extension methods are less discoverable and more limited in functionality than instance methods. For those reasons, it is recommended that extension methods be used sparingly and only in situations where instance methods are not feasible or possible. Und als ob das noch nicht genug wäre, schickt er noch eine kleine Drohung hinterher:
Extension members of other kinds, such as properties, events and operators,
are being considered but are currently not supported.
top Lambda-ExpressionsLambda-Expressions ähneln vom Konzept her den bislang schon bekannten anonymen Methoden, nur mit dem Unterschied, dass man als Body entweder eine Expression oder ein Statement-Block sein kann, wobei bei einer anonymen Methode der Body nur ein Statement-Block sein kann. Sie beginnen mit einer in runden Klammern eingefassten Parameterliste, bei denen man die Klammern dann weglassen kann, wenn es genau einen ungetypten Parameter gibt. Gefolgt wird die Parameterliste von dem Terminalsymbol "=>" und entweder einer Expression oder einem Statementblock:
Eine Lambda-Expression kann man überall dort einsetzen, wo eine anonyme Methode gestattet ist (typischerweise in Verbindung mit einem Delegate), da man einer Lambda-Expression keinen Namen geben kann wie einer normalen Methode. Eine Lambda-Expression L ist zu einem Delegate D kompatibel, wenn folgende Bedingungen erfüllt sind: ref - oder out -Parameter sein
void ist und der Body von L
eine Expression ist, ist dieser korrekt, wenn er eine Statement-Expression
ist (In-, Dekrement, Zuweisung, Objekterzeugung, Aufruf).
void ist und der Body von L
ein Statement ist, ist dieser korrekt, wenn er kein return
enthält.
void ist und der Body von L
eine Expression ist, ist dieser korrekt, wenn er zu dem Rückgabetyp von D
implizit kompatibel ist.
void ist und der Body von L
ein Statement ist, ist dieser korrekt, wenn jedes return einen
zum Rückgabetyp von D kompatiblen Wert zurückliefert.
Die Typinferenz einer Lambda-Expression L läuft nach den folgenden Regeln ab: top Object- und Collection-InitializerObject-Initializer dienen dazu, Felder oder Properties eines Objekts bei der Erzeugung mit Werten zu belegen. Dazu müssen diese jedoch öffentlich zugänglich sein:
In obigem Beispiel wird ein Objekt der Klasse "A" erzeugt, das zwei
Felder oder Properties namens Mit einem Collection-Initializer kann man eine Collection (ein Typ, der
das Interface
In obigem Beispiel wird die Liste mit den Werten 1, 3, 5, 2 belegt wird, dergestalt, dass intern für jeden Wert im Initializer einmal ICollection<T>.Add<T> aufgerufen wird. topanonyme TypenÄhnlich zu den bereits bekannten anonymen Methoden, wird C# 3.0 auch die
Möglichkeit bieten, anonyme Typen zu erzeugen. Dazu eignet es sich,
diesen einer implizit getypten lokalen Variablen zuzuweisen, da man bei
Es wird dabei ein rudimentäres Objekt erzeugt, in dem für jeden im Initializer stehenden Bezeichner (hier: name, lage) ein Feld des entsprechenden Typen angelegt wird, auf das man über eine Property des angegebenen Namens (hier: name, lage) zugreifen kann. Man kann auch die Initialisierung weglassen, wenn der Bezeichner ein Feld ist. Dann wird auch eine Property des Bezeichners angelegt und das Feld erhält den Typ der Variablen:
Zwei anonyme Typen sind zueinander kompatibel, wenn die Bezeichner den selben Namen haben und in der selben Reihenfolge deklariert werden. Man kann allerdings nicht ein Objekt der anonymen Klasse selbst explizit erzeugen, da diese vom Compiler angelegt wird. topQuery-ExpressionsNachdem C# 3.0 ja bereits mit den Lambda-Expressions einen kleinen
Abstecher in die Welt der funktionalen Programmierung unternommen hat,
wird es künftig auch die Möglichkeit geben, mit SQL-artigen Abfrage-Ausdrücken
bestimmte Werte aus einem oder mehreren Elementen, die das Interface
Die Syntax erinnert wie gesagt an SQL-Statements, wobei eine Query-Expression
zwingend mit einer Die wichtigsten Klauseln im Überblick: from :
spezifiziert eine Laufvariable über ein bestimmtes IEnumerable<T>:from p in Personen
join :
verknüpft eine Tabelle mit einer zweiten:join w in Wohnorte on p.Id equals w.Id
let : speichert einen Wert in einer Variable zwischen:let foo = 8
where :
schränkt die ermittelten Werte nach gewissen Bedingungen ein:where w.Ort == "Hamburg"
orderby : sortiert nach bestimmten Feldern:orderby w.Ort descending
group : gruppiert das Ergebnis nach gewissen Regeln:group w by w.Ort
select : sucht die gewünschten Felder aus der Abfrage:select new { Ort = w.Ort }
zum Beispiel:
In obigem Beispiel sehen wir eine Abfrage, die aus zwei Tabellen zunächst
eine Verknüpfung bildet, diese mit into gruppiert in der Variable g
zwischenspeichert, auf der dann eine Methode Mit anderen Worten: Die Abfrage ermittelt alle Orte, in der mehr als 2
dieser tollen Sänger wohnen. Es wird ein neues Objekt erzeugt, in dem
die entsprechden Orte und die Anzahl der dort lebenden Sänger in einem
Vom Compiler werden die Query-Expressions letztendlich in die allgemein bekannte Punkt-Notation übersetzt. So würde der obige Ausdruck in etwa in folgenden Ausdruck übersetzt:
Dem Programmierer steht es dabei offen, welche Notation ihm am meisten behagt. topandere Projekte im LINQ-ProjektIm Rahmen des DLINQ-Projekts, besteht die Möglichkeit, auch eine reale Datenbank anstatt eines o.e. Elements zu verwenden. Das XLINQ-Projekt gestattet das Arbeiten mit XML-Daten. top |