Geleitwort | 5 |
Vorwort | 7 |
Inhalt | 7 |
Zielpublikum | 8 |
Inhalt | 9 |
1 C# und das .NET-Framework | 15 |
1.1 Ähnlichkeiten zwischen C# und Java | 15 |
1.2 Unterschiede zwischen C# und Java | 17 |
1.3 Das .NET-Framework | 18 |
Abb. 1–1 Grobarchitektur des .NET-Frameworks | 19 |
Common Language Runtime | 19 |
Abb. 1–2 Quellcode, CIL-Code und Maschinencode | 20 |
Assemblies | 20 |
Abb. 1–3 Vom Compiler erzeugtes Assembly Prog.exe | 21 |
ADO.NET | 22 |
ASP.NET | 22 |
Web-Services | 23 |
1.4 Übungsaufgaben | 24 |
2 Erste Schritte | 25 |
2.1 Hello World | 25 |
2.2 Gliederung von Programmen | 26 |
Abb. 2–1 Gliederung von Programmen | 26 |
Programme aus mehreren Dateien | 26 |
2.3 Symbole | 27 |
2.4 Übungsaufgaben | 30 |
3 Typen | 31 |
Abb. 3–1 Typenhierarchie | 31 |
Tabelle 3–1 Werttypen und Referenztypen | 32 |
3.1 Einfache Typen | 32 |
Tabelle 3–2 Einfache Typen | 32 |
Abb. 3–2 Kompatibilitätsbeziehung zwischen einfachen Typen | 33 |
3.2 Enumerationen | 33 |
3.3 Arrays | 34 |
Abb. 3–3 Ausgefranste und rechteckige mehrdimensionale Arrays | 35 |
3.4 Strings | 37 |
Tabelle 3–3 Stringoperationen (Auszug) | 38 |
3.5 Structs | 38 |
3.6 Klassen | 39 |
Tabelle 3–4 Klassen versus Structs | 40 |
3.7 object | 40 |
3.8 Boxing und Unboxing | 41 |
Abb. 3–4 Boxing eines int-Werts | 41 |
3.9 Übungsaufgaben | 42 |
4 Ausdrücke | 45 |
Tabelle 4–1 Operatoren nach Priorität geordnet | 45 |
4.1 Arithmetische Ausdrücke | 45 |
4.2 Vergleichsausdrücke | 46 |
4.3 Boolesche Ausdrücke | 47 |
4.4 Bit-Ausdrücke | 47 |
4.5 Shift-Ausdrücke | 47 |
4.6 Überlaufprüfung | 48 |
4.7 typeof | 48 |
4.8 sizeof | 49 |
4.9 Übungsaufgaben | 49 |
5 Deklarationen | 51 |
5.1 Deklarationen in Namensräumen | 52 |
5.2 Deklarationen in Klassen, Structs und Interfaces | 53 |
5.3 Deklarationen in Enumerationstypen | 54 |
5.4 Deklarationen in Blöcken | 54 |
5.5 Übungsaufgaben | 56 |
6 Anweisungen | 57 |
6.1 Leeranweisung | 57 |
6.2 Zuweisung | 57 |
6.3 Methodenaufruf | 58 |
6.4 if-Anweisung | 58 |
6.5 switch-Anweisung | 59 |
6.6 while-Anweisung | 60 |
6.7 do-while-Anweisung | 60 |
6.8 for-Anweisung | 60 |
6.9 foreach-Anweisung | 61 |
6.10 break- und continue-Anweisungen | 62 |
6.11 goto-Anweisung | 62 |
Abb. 6–1 Endlicher Automat | 63 |
6.12 return-Anweisung | 63 |
6.13 Übungsaufgaben | 64 |
7 Ein-/Ausgabe | 65 |
7.1 Ausgabe auf den Bildschirm | 65 |
7.2 Formatierte Ausgabe | 65 |
Platzhalter-Syntax | 66 |
Tabelle 7–1 Die wichtigsten Formatierungscodes | 67 |
Stringformatierung | 67 |
Vereinfachte Platzhalter in Formatstrings | 68 |
7.3 Ausgabe auf eine Datei | 68 |
7.4 Eingabe von der Tastatur | 69 |
7.5 Eingabe von einer Datei | 69 |
7.6 Lesen der Kommandozeilenparameter | 70 |
7.7 Übungsaufgaben | 71 |
8 Klassen und Structs | 73 |
8.1 Sichtbarkeitsattribute | 74 |
8.2 Felder | 76 |
Statische Felder | 76 |
Abb. 8–1 Statische und nicht statische Felder | 77 |
8.3 Methoden | 77 |
Statische Methoden | 78 |
Parameter | 78 |
Variable Anzahl von Parametern | 80 |
Überladen von Methoden | 81 |
Optionale Parameter | 82 |
Benannte Parameter | 83 |
8.4 Konstruktoren | 84 |
Konstruktoren in Klassen | 84 |
Konstruktoren in Structs | 85 |
Statische Konstruktoren | 86 |
8.5 Destruktoren | 86 |
8.6 Properties | 87 |
8.7 Indexer | 90 |
8.8 Überladene Operatoren | 92 |
Tabelle 8–1 Überladbare Operatoren | 93 |
Konversionsoperatoren | 94 |
8.9 Kurzform für Methoden | 95 |
8.10 Geschachtelte Typen | 96 |
8.11 Partielle Typen | 97 |
8.12 Partielle Methoden | 98 |
8.13 Statische Klassen | 99 |
8.14 Unterschiede zu Java | 99 |
8.15 Übungsaufgaben | 100 |
9 Vererbung | 103 |
9.1 Deklaration von Unterklassen | 103 |
9.2 Kompatibilität zwischen Klassen | 105 |
Tabelle 9–1 Statischer und dynamischer Typ einer Variablen | 105 |
9.3 Überschreiben und Verdecken von Elementen | 106 |
9.4 Dynamische Bindung | 109 |
Dynamische Bindung und Verdecken von Methoden | 110 |
Das Problem der zerbrechlichen Basisklassen | 110 |
9.5 Konstruktoren in Ober- und Unterklasse | 112 |
Tabelle 9–2 Impliziter Aufruf des parameterlosen Konstruktors der Basisklasse | 112 |
9.6 Abstrakte Klassen | 113 |
Abstrakte Properties und Indexer | 113 |
9.7 Versiegelte Klassen | 114 |
9.8 Die Klasse Object | 115 |
9.9 Übungsaufgaben | 117 |
10 Interfaces | 119 |
10.1 Deklaration und Verwendung von Interfaces | 119 |
Abb. 10–1 Arbeiten mit einem Objekt versus Arbeiten mit einer Interfacevariablen | 120 |
10.2 Operationen auf Interfaces | 121 |
10.3 Erweiterung von Interfaces | 122 |
Abb. 10–2 Abhängigkeiten zwischen ISimpleReader, IReader, Terminal und File | 122 |
10.4 Namenskonflikte | 123 |
10.5 Interface IDisposable | 124 |
using-Anweisung | 125 |
10.6 Übungsaufgaben | 125 |
11 Delegates und Events | 127 |
11.1 Einfache Delegates | 127 |
11.2 Multicast-Delegates | 128 |
11.3 Erzeugen von Delegate-Werten | 128 |
Vereinfachte Delegate-Zuweisung | 129 |
11.4 Ereignisse (Events) | 130 |
11.5 Anonyme Methoden | 131 |
11.6 Übungsaufgaben | 133 |
12 Ausnahmen | 135 |
12.1 try-Anweisung | 135 |
12.2 Ausnahmeklassen | 137 |
Abb. 12–1 Auszug aus der Hierarchie der Ausnahmeklassen | 138 |
12.3 Auslösen von Ausnahmen | 138 |
Abb. 12–2 Suche nach einer passenden catch-Klausel | 139 |
12.4 Ausnahmen in aufgerufenen Methoden | 140 |
12.5 Ausnahmen in Multicast-Delegates | 140 |
Abb. 12–3 Suche nach einer catch-Klausel in Zusammenhang mit Delegates | 140 |
12.6 Übungsaufgaben | 141 |
13 Namensräume und Assemblies | 143 |
13.1 Namensräume | 143 |
C#-Namensräume versus Java-Pakete | 144 |
Abb. 13–1 Pakete werden in Java auf Verzeichnisse abgebildet, Namensräume in C# nicht | 145 |
13.2 Assemblies | 146 |
13.2.1 Assemblies und Module | 146 |
Abb. 13–2 Assembly A.exe, bestehend aus drei Modulen | 147 |
13.2.2 Versionierung von Assemblies | 147 |
Private und öffentliche Assemblies | 147 |
Starke Namen | 148 |
Versionsnummer | 148 |
Abb. 13–3 A.exe merkt sich die Versionsnummer von Lib.dll | 149 |
Signierte Assemblies | 149 |
Abb. 13–4 Signieren eines Assemblies | 150 |
Abb. 13–5 Überprüfung der Unterschrift eines Assemblies | 150 |
13.2.3 Assemblies versus Namensräume | 150 |
Abb. 13–6 Ein Assembly, bestehend aus den Klassen A.C2 und B.C3 sowie aus einem Icon | 151 |
13.3 Übungsaufgaben | 151 |
14 Generische Bausteine | 153 |
14.1 Generische Typen | 154 |
14.2 Constraints | 155 |
Konstruktor-Constraints | 156 |
14.3 Vererbung bei generischen Typen | 156 |
Zuweisungskompatibilität zwischen generischen Typen | 157 |
Überschreiben von Methoden | 158 |
Laufzeittypprüfungen | 158 |
14.4 Generische Methoden | 158 |
14.5 Generische Delegates | 159 |
14.6 Nullwerte | 161 |
14.7 Ko- und Kontravarianz bei generischen Typen | 161 |
Typsichere Kovarianz | 162 |
Abb. 14–1 Kovarianz bei generischen Typen | 163 |
Typsichere Kontravarianz | 163 |
Abb. 14–2 Kontravarianz bei generischen Typen | 164 |
Beispiel | 164 |
Abb. 14–3 Beispiel-Klassenhierarchie | 164 |
14.8 Was geschieht hinter den Kulissen? | 165 |
14.9 Unterschiede zu Java | 165 |
14.10 Übungsaufgaben | 166 |
15 Threads | 169 |
15.1 Die Klasse Thread | 169 |
Beispiel | 171 |
15.2 Zustände eines Threads | 172 |
Abb. 15–1 Zustandsübergangsdiagramm eines Threads | 172 |
15.3 Abbrechen eines Threads | 173 |
15.4 Thread-Synchronisation | 174 |
Abb. 15–2 Zwei Threads führen gleichzeitig die Anweisung x = x + 1 | aus | 174 |
Die lock-Anweisung | 174 |
Die Klasse Monitor | 176 |
Wait und Pulse | 176 |
Abb. 15–3 Systemverklemmung bei Verwendung von Pulse statt PulseAll | 178 |
15.5 Übungsaufgaben | 179 |
16 Iteratoren | 181 |
16.1 Allgemeine Iteratoren | 181 |
yield-Anweisung | 183 |
16.2 Spezifische Iteratoren | 183 |
Übersetzung spezifischer Iteratoren | 185 |
16.3 Übungsaufgaben | 186 |
17 Attribute | 187 |
17.1 Schreibweise von Attributen | 187 |
17.2 Parameter von Attributen | 188 |
17.3 Attribute für spezifische Programmelemente | 189 |
17.4 Attribut Serializable | 190 |
Abb. 17–1 Ursprüngliche Liste und neue Liste nach Serialisierung und Deserialisierung | 191 |
17.5 Attribut Conditional | 192 |
17.6 Attribut DllImport | 193 |
Abb. 17–2 Ein von einer Native-Funktion erzeugtes Fenster | 193 |
17.7 Deklaration eigener Attribute | 194 |
17.8 Übungsaufgaben | 195 |
18 Dokumentationskommentare | 197 |
18.1 XML-Elemente | 197 |
Beispiel | 198 |
18.2 Erzeugte XML-Datei | 199 |
18.3 Übungsaufgaben | 200 |
19 Auszug aus der .NET-Klassenbibliothek | 201 |
Tabelle 19–1 Auszug der Namensräume und Typen der .NET-Bibliothek | 202 |
19.1 Hilfsklassen | 202 |
StringBuilder | 202 |
Math | 203 |
Random | 204 |
Convert | 204 |
19.2 Collections | 205 |
Abb. 19–1 Auszug der wichtigsten Collection-Typen | 205 |
Array | 206 |
ArrayList | 206 |
Hashtable | 208 |
ListDictionary | 209 |
SortedList | 209 |
Stack | 210 |
Queue | 210 |
BitArray | 211 |
Iterieren über Collections | 212 |
Generische Collection-Typen | 213 |
19.3 Ein-/Ausgabe | 214 |
Datenströme | 214 |
Abb. 19–2 Hierarchie der Stream-Klassen | 215 |
Reader | 216 |
Abb. 19–3 Reader-Klassen (Auszug) | 216 |
Writer | 217 |
Abb. 19–4 Writer-Klassen (Auszug) | 217 |
File und FileInfo | 218 |
Abb. 19–5 Auszug aus den Klassen File und FileInfo | 218 |
Directory und DirectoryInfo | 218 |
Abb. 19–6 Auszug aus den Klassen Directory und DirectoryInfo | 219 |
19.4 Reflection | 220 |
Type | 220 |
Assembly | 222 |
19.5 Übungsaufgaben | 224 |
20 LINQ | 227 |
20.1 Motivation | 227 |
20.2 Lambda-Ausdrücke | 228 |
Lambda-Ausdrücke als Parameter | 229 |
Lambda-Ausdrücke als Prädikate | 230 |
Lambda-Ausdrücke mit mehreren Parametern | 230 |
Lambda-Ausdrücke mit Anweisungsblöcken | 231 |
Beispiele | 232 |
20.3 Erweiterungsmethoden | 232 |
20.4 Objektinitialisierer | 234 |
Initialisierer für Collections | 235 |
20.5 Anonyme Typen | 236 |
Schlüsselwort var | 237 |
20.6 Query-Ausdrücke | 238 |
Query-Syntax | 239 |
Laufvariablen | 240 |
Gruppierung | 241 |
Joins | 242 |
Gruppen-Joins | 244 |
let | 244 |
20.7 LINQ und XML | 245 |
XElement und XAttribute | 245 |
Erzeugen von XML-Daten aus einer Wertefolge | 246 |
Erzeugen einer Wertefolge aus XML-Daten | 246 |
20.8 Übungsaufgaben | 247 |
21 Asynchrone Methoden und Parallelität | 249 |
21.1 Asynchronität | 249 |
Abb. 21–1 Synchrone und asynchrone Methodenaufrufe | 249 |
21.2 Tasks | 250 |
21.3 Asynchrone Methoden | 252 |
Abb. 21–2 Ablauf von DoAsync() | Task ist bereits vor der await-Anweisung fertig | 252 |
Abb. 21–3 Ablauf von DoAsync() | Task ist erst nach der await-Anweisung fertig | 253 |
Umwandlung von synchronen in asynchrone Methoden | 254 |
Einschränkungen und Hinweise | 255 |
Asynchronität in Schleifen | 256 |
Abb. 21–4 Asynchrone Operation in einer Schleife | 256 |
Weiteres Beispiel | 257 |
Abb. 21–5 Verzahnter Steuerfluss beim Aufruf von DoAsync(), GetAsync() und ReadAsync() | 258 |
21.4 Explizite Parallelität | 258 |
21.5 Übungsaufgaben | 260 |
22 Tupel | 261 |
22.1 Tupel-Typen | 261 |
22.2 Zuweisungen | 262 |
22.3 Anwendungen | 263 |
Funktionen mit mehreren Rückgabewerten | 263 |
Tupel-Typen als Typparameter | 264 |
Tupel-Typen als Projektionen | 264 |
22.4 Zerlegung von Tupeln | 265 |
Zerlegung unter Weglassung einzelner Elemente | 266 |
22.5 Dekonstruktoren für Klassen und Structs | 266 |
22.6 Übungsaufgaben | 267 |
23 Pattern Matching | 269 |
Pattern Matching in switch-Anweisungen | 270 |
24 Interoperabilität mit COM | 273 |
24.1 COM-Objekte von .NET aus ansprechen | 274 |
Erzeugen eines Assemblies (tlbimp) | 274 |
Abb. 24–1 Ansicht von MyLibNET.dll in ildasm | 275 |
Registrieren der COM-Objekte (regsvr32) | 275 |
Benutzung des Assemblies | 276 |
Spät gebundener Methodenaufruf | 276 |
24.2 .NET-Assemblies von COM aus ansprechen | 277 |
Früh gebundener Methodenaufruf | 277 |
Spät gebundener Methodenaufruf | 279 |
24.3 Übungsaufgaben | 279 |
Abb. 24–2 Beispiele für Figuren unter Microsoft Agent | 279 |
25 Dynamisch getypte Variablen | 281 |
25.1 Typ dynamic | 281 |
Abb. 25–1 Alle Typen sind mit dynamic kompatibel | 281 |
25.2 Operationen auf dynamic-Variablen | 283 |
Implementierung der dynamischen Methodensuche | 284 |
26 Diverses | 285 |
26.1 Null-fähige Werttypen | 285 |
Rechnen mit null-fähigen Typen | 287 |
Konversion zwischen null-fähigen Typen und Originaltypen | 287 |
26.2 Bedingter Zugriff über Referenzen | 288 |
Bedingter Aufruf von Delegates | 289 |
26.3 using static | 289 |
26.4 Geschachtelte Methoden | 290 |
26.5 Rückgabe von Funktionswerten by reference | 291 |
27 Fallstudien | 293 |
27.1 Anwendungen mit grafischer Benutzeroberfläche | 293 |
Tabelle 27–1 Einige der in Windows Forms benötigten Typen | 293 |
Spezifikation eines Dateivergleichsprogramms | 294 |
Abb. 27–1 Benutzeroberfläche des Dateivergleichswerkzeugs | 294 |
Erstellen der Benutzeroberfläche mit Visual Studio .NET | 295 |
Abb. 27–2 Anlegen eines neuen Projekts | 295 |
Abb. 27–3 Entwurfsfläche mit Toolbox-Palette und Property-Fenster | 296 |
Tabelle 27–2 Properties der GUI-Elemente des Dateivergleichsprogramms | 297 |
Erzeugter Code | 298 |
27.2 Ein Web-Service für Börsenkurse | 302 |
Abb. 27–4 Eine Applikation holt sich Informationen von verschiedenen Web-Services | 303 |
Spezifikation eines Web-Services für Börsenkurse | 303 |
Serverseitige Implementierung | 303 |
Abb. 27–5 Von .NET generierte Seite zum Testen des Web-Services | 305 |
Clientseitige Implementierung | 306 |
Abb. 27–6 Aufruf der Web-Service-Methode GetQuote | 307 |
27.3 Dynamische Webseiten mit ASP.NET | 307 |
Abb. 27–7 Benutzeroberfläche einer Webseite zur Abfrage von Börsenkursen | 308 |
Layout der Webseite | 308 |
Hintergrundcode | 310 |
Einbinden weiterer Klassen | 311 |
Benutzung der Webseite | 312 |
Interaktive Erstellung von Webseiten | 312 |
Weitere Möglichkeiten von ASP.NET | 312 |
27.4 Übungsaufgaben | 313 |
A Anhang | 315 |
A.1 Compileroptionen | 315 |
Optionen zur Bestimmung der erzeugten Ausgabe | 315 |
Optionen zum Einbinden von Bibliotheken | 316 |
Weitere Optionen (Auswahl) | 316 |
Beispiele | 317 |
Tabelle A–1 Beispiele für den Aufruf des C#-Compilers | 317 |
A.2 Werkzeuge unter .NET | 318 |
A.2.1 ildasm | 318 |
Abb. A–1 Ansicht eines Assemblies Primes.exe in ildasm | 318 |
Abb. A–2 Links: Manifest von Primes.exe | rechts: CIL-Code der Methode PrintPrimes | 318 |
A.2.2 Globaler Assembly-Cache | 319 |
Signieren von Assemblies | 319 |
Verzögertes Signieren von Assemblies | 320 |
Verwaltung des globalen Assembly-Cache | 321 |
Abb. A–3 Globaler Assembly-Cache | 321 |
A.3 Grammatik von C# | 322 |
Tabelle A–2 Metazeichen in Grammatikregeln | 322 |
Zeichenmengen | 322 |
Namen und Konstanten | 323 |
Deklarationen | 323 |
Typen | 325 |
Anweisungen | 326 |
Ausdrücke | 327 |
A.4 Unicode und ASCII | 329 |
Tabelle A–3 Der ASCII-Zeichensatz (entspricht den ersten 128 Zeichen von Unicode) | 329 |
Literatur | 331 |
Index | 333 |