Armin Hanisch
-c#
ADDISON-WESLEY An imprint of Pearson Education
München • Boston • San Francisco • Harlow, England Don Mills, Ontario • Sydney • Mexico City
Madrid • Amsterdam
Inhaltsverzeichnis
IßMlf >Inhaltsverzeichnis
Vorwort 17
Basics-Teil 1 19
Einführung 21 1.1 Noch eine neue Programmiersprache? 21
1.2 An wen richtet sich das Buch? 21 1.2.1 Leserkenntnisse 22 1.2.2 Systemvoraussetzungen 22
1.3 Konventionen 23 1.4 Gliederung 24 1.5 Die CD zum Buch 25 Das .NET-Framework 27 2.1 Was ist .NET? 27
2.1.1 DieBausteinevon.NET 27 2.1.2 Die Rolle von Windows 28 2.2 Das .NET-Framework im Überblick 28
2.2.1 Die Vorteile des .NET-Frameworks 29 2.2.2 Das Common Type System 32 2.2.3 Die Common Language Specification (CLS) 33
2.2.4 Die .NET-Laufzeitumgebung (CLR) 34
2.3 .NET aus Anwendungssicht 35 2.3.1 Übersetzung 35 2.3.2 Laden und Ausführung 36
2.3.3 Ressourcenverwaltung 37 2.4 .NET aus Entwicklersicht 37
2.4.1 Ein klarer Schnitt? 38 2.4.2 Die Bequemlichkeit der Infrastruktur 39
2.4.3 Die Namensräume 40 2.4.4 Wo anfangen? 40 2.5 Zusammenfassung 43 C# Sightseeing Tour 45 3.1 Das Problem 45
3.1.1 Ein Werkzeug für .NET 46
3.2 Designziele von C# 47 3.2.1 Produktivität 47 3.2.2 Stabiler und sicherer Code 47
3.2.3 Praxistauglichkeit 48 3.2.4 Modularität 49 3.2.5 Nutzung aller .NET-Möglichkeiten 49
GEES Inhaltsverzeichnis
•
3.2.6 Echte Objektorientierung 50 3.2.7 Komponentenorientierte Entwicklung 50
3.3 C# im Überblick 52 3.3.1 Wofür C#? 52 3.3.2 Am Anfang war »Hallo, Welt« 54
3.3.3 Grundprinzipien von C#-Programmen 55
3.3.4 Datentypen in C# 57 3.3.5 Kontrollstrukturen & Operatoren 59
3.3.6 Klassen & Interfaces 59 3.3.7 Attribute & Reflection 60 3.3.8 Strukturierte Fehlerbehandlung 60 3.3.9 Interoperabilität mit COM & Wn32 61 3.3.10 Bedingte Kompilierung / Präprozessor 62
3.3.11 Namespaces 62 3.3.12 Formatierte Stringausgabe in C# 63
3.4 Zusammenfassung 64 Namensräume 65 4.1 Grundlagen 65 4.2 Definition eines Namensraums 66
4.2.1 Hierarchische Namensräume 67 4.3 Nutzen eines Namensraums mit using 68 4.4 Namenskonflikte beim Import mit using 69
4.4.1 Aliase 70 4.5 Die wichtigsten Namensräume 71
4.6 Zusammenfassung 72 4.7 Übungen 73 Daten, Typen, Variablen 75
5.1 Wert- und Referenztypen 75 5.2 Alles ist ein Objekt 75
5.2.1 Boxing und Unboxing 76 5.2.2 Boxing und Literale 76 5.3 Einfache Datentypen 77
5.3.1 Bool 78 5.3.2 Char 79 5.3.3 String 79 5.3.4 Nummerische Literale 80
5.4 Bezeichner 81 5.5 Konstanten 82
5.5.1 Echte Konstanten 82 5.5.2 Konstantenausdrücke 83 5.5.3 Read-Only Variablen 84
5.6 Variablen 85 5.6.1 Deklaration 85
5.6.2 Initialisierung von Variablen 86
Inhaltsverzeichnis f c B J j g p
•
5.6.3 Variablenkategorien in C# 86
5.6.4 Standardwerte 91 5.7 Zusammenfassung 92 5.8 Übungen 93
6.1
6.2
OOP-Konzepte 6.1.1
6.1.2 6.1.3 6.1.4 6.1.5
Abstraktion Kapselung
Kohäsion und Kopplung Vererbung
Polymorphie Terminologie
6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.2.6 6.2.7 6.2.8 6.2.9
Klasse (dass)
Feld / Attribut (field, member variable) Eigenschaften (property)
Methode (method)
Instanziierung (instantiation, creation) Konstruktoren (constructor)
Objekt (object, class instance) Freigabe / Destruktoren (destructor) Alles ist ein Objekt
Zusammenfassung Übunger
;n in C#
i
96 97 97 98 99 100 100 100 101 101 102 103 104 105 105 106 107 108 . . . 109 6.3
6.4
7.1 Klassendefinition 109 7.2 Zugriff auf Klassen und Mitglieder 109
7.2.1 Zugriff auf Klassen 110 7.2.2 Zugriff auf Klassenmitglieder 111
7.3 Methoden 112 7.3.1 Definition 113 7.3.2 Parameterübergabe 113
7.3.3 Überladen von Methoden 117 7.3.4 Variable Anzahl von Parametern 119
7.4 Instanzen erzeugen 120 7.5 Konstruktoren und Destruktoren 121
7.5.1 Konstruktoren 121 7.5.2 Destruktoren 123 7.6 Eigenschaften 125
7.6.1 Deklaration von Eigenschaften 127 7.6.2 OOP-Vorteile von C#-Eigenschaften 128 7.6.3 Der spezielle Bezeichner value 130 7.6.4 Nur-Lese-Eigenschaften 130 7.7 Statische Klassenmitglieder 131
7.7.1 Das Schlüsselwort static 132
p Inhaltsverzeichnis
7.8 7.7.2 7.7.3
Zugriff auf statische Klassenmitglieder Statische Konstruktoren
Übungen
8.1 8.2
8.3
8.4
8.5
Anweisungen
8.1.1 Schlüsselwörter Ablaufsteuerung 8.2.1
8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.2.7
Aus der Gruft - GOTO Verzweigungen - IF / ELSE Bedingte Schleifen - DO & WHILE Festgelegte Schleifen - FOR Schleifen in Auflistungen - FOREACH Raus hier - BREAK & CONTINUE Mehrfachauswahl - SWITCH Synchronisation, Überlaufprüfung 8.3.1
8.3.2 lock
checked, unchecked Operatoren
8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.4.6 8.4.7 Übunger
Arithmetische Operatoren Logische Operatoren Relationale Operatoren Zuweisungen
Typ-Operatoren Der Bedingungsoperator Zugriffsoperatoren
132 134 136 , 1 3 7 137 138 139 139 140 142 143 144 144 145 146 146 146 146 147 148 151 152 152 155 156 156
10
Going professional - Teil II 157
Abzählen in C# - Enums 159 9.1
9.2 9.3 9.4 9.5 9.6
Die Grundlagen Enums implementieren
Basisdatentypen für Aufzählungen 9.3.1 Aufzählungen als Bitflags Ausgabe von Aufzählungstypen Zusammenfassung
Übunger i
10.1 Arrays 10.1.1 10.1.2 10.1.3 10.1.4
Deklaration
Erzeugung und Initialisierung Konvertierungen bei Arrays Die Klasse System.Afray
159 159 162 163 164 167 168 169 169 169 172 173 174
8
Inhaltsverzeichnis
10.2 Structs 175 10.2.1 Mehr als nur Daten 175
10.2.2 Deklaration und Initialisierung von structs 176
10.2.3 Verschachtelte structs 179 10.2.4 Layout von structs 180
10.3 Zusammenfassung 181 10.4 Übungen 181 11 Vererbung 183
11.1 Einfache Vererbung 183 11.1.1 Zugriff über die Basisklasse 187
11.1.2 Zugriff auf Mitglieder der Basisklasse 187 11.1.3 Zugriff auf Konstruktoren der Basisklasse 188
11.2 Steuern der Vererbung 188 11.2.1 p i e Notwendigkeit virtueller Methoden 188
11.2.2 Virtuelle Methoden 189 11.2.3 Der Unterschied zwischen new und override 191
11.2.4 Abstrakte Klassen 193 11.2.5 Verhindern der Vererbung 194 11.3 Was alle erben - System.Object 195
11.4 Übungen 198 12 Fehlerbehandlung 199
12.1 Versuch und Fehler - try/catch 199 12.1.1 Explizites catch 199 12.1.2 Generelles catch 200 12.2 Die Hierarchie von Exceptions 201 12.3 Ausnahmen - System.Exception Sc Co 203
12.4 Schutzblocks mit finally 205 12.5 Kaskadierende Exceptions 206 12.6 Exceptions selbst gemacht 208
12.6.1 Ableitung der Exception-Klasse 208 12.6.2 Auslösen einer Exception 209
12.7 Zusammenfassung 211 12.8 Übungen 212 13 Schnittstellen (Interfaces) 213
13.1 Probleme klassenbasierter Vererbung 213
13.2 Was sind Interfaces 216 13.2.1 Deklaration einer Schnittstelle in C# 217
13.2.2 Implementieren einer Schnittstelle 218 13.2.3 Schnittstellen mit Eigenschaften 219
13.3 Arbeiten mit Schnittstellen 219 13.3.1 Benutzen einer Schnittstelle 219
13.3.2 Testen auf eine bestimmte Schnittstelle 222 13.3.3 Typumwandlungen für Schnittstellen 223
S*fü3 Inhaltsverzeichnis
•
13.4 Implementieren mehrerer Schnittstellen 223 13.4.1 Definitionen der Klassen und Schnittstellen 224
13.4.2 Explizite Schnittstellenimplementierung 227
13.5 Zusammenfassung 231 13.6 Übungen 232 14 Ein- und Ausgabe 233
14.1 Dateioperationen 233 14.1.1 Die Klasse Path 235 14.1.2 File und Directory 237 14.2 Das Stream-Konzept 240
14.2.1 Streamklassen 240 14.2.2 Lesen und Schreiben einer Textdatei 242
14.2.3 Codierung von Dateien 243 14.2.4 Peek - 'Nur mal einen Blick drauf werfen' 245
14.2.5 Lesen und Schreiben von Binärdateien 246
14.2.6 Stream-Eigenschaften 247 14.3 Lesen und Schreiben von XML-Dateien 248
14.3.1 Zugriffsarten 248 14.3.2 Die Beispieldatei 249 14.3.3 XML-Dateien laden und anzeigen 250
14.3.4 Suchen und Ändern im Dokument 254 14.3.5 Einfügen und Löschen von Knoten 255 14.3.6 XmlDocument-lnstanzen in Dateien speichern 256
14.3.7 Lesen von XML-Dateien mit XmIReader 257 14.3.8 Schreiben von XML-Dateien mit XmIWriter 261
14.4 Übungen 264 15 Strings 265
15.1 String-Literale — 265 15.2 System.String im Überblick 266
15.2.1 Methoden der String-Klasse 267
15.3 Strings formatieren 270 15.3.1 Standard-Formate 270 15.3.2 Standard-Formatierung 271
15.4 Die StringBuilder-Klasse 275 15.4.1 Erzeugen eines StringBuilders 276
15.4.2 Eigenschaften der Klasse 276 15.4.3 StringBuilder-Methoden 277 15.5 String oder StringBuilder? 277
15.6 Übungen 279 16 Konvertierungen 281
16.1 Implizite Konvertierungen 281 16.1.1 .NET-Datentypen 282 16.2 Explizite Konvertierungen 283 16.3 Benutzerdefinierte Konvertierungen 283
10
Inhaltsverzeichnis
283 285 286 286 287 287 289 290
17 Windows Forms 291 291
292 297 297 299 299 304 306 307 307 312 312 312 313 315 316
18 Indexer und Auflistungen 317
18.1 Indexer 317 18.1.1 Deklaration eines Indexers 317
18.1.2 Zugriff über einen Indexer 320 18.1.3 Designüberlegungen 321 18.1.4 Indexer und Eigenschaften im Vergleich 324
18.2 Auflistungen 324 18.2.1 Auflistungsklassen 325
18.2.2 Auflistungen, Indexer Sc foreach 329
18.3 Zusammenfassung 334 19 Fehlersuche mit C# 335
19.1 Das Attribut [Conditional] 335 19.2 Die Klassen Debug und Trace 335
19.2.1 Mitglieder von Debug und Trace 337
19.2.2 Asserts 338 19.2.3 Ausgabe der Diagnosemeldungen 339
19.2.4 Das Listener-Konzept für Debug-Output 341 16.4
16.5
16.3.1 Der Beispieltyp ClockTime 16.3.2 Implizite Konvertierungsroutine 16.3.3 Explizite Konvertierungsroutine 16.3.4 Implizit oder explizit?
16.3.5 Auflösungskonflikte 16.3.6 Die komplette Struktur Zusammenfassung
Übungen Windows Forms 17.1
17.2
17.3
17.4
17.5
17.6 17.7
Einführung
Das Programmiermodell
17.2.1 Wo bleibt die Formulardatei?
17.2.2 Läuft und läuft und läuft - Application.Run Steuerelemente
17.3.1 Steuerelemente hinzufügen
17.3.2 Ereignisbehandlung für Steuerelemente Wichtige Klassen
17.4.1 MessageBoxen einst und jetzt 17.4.2 Menüs
17.4.3 Bestehende Ereignisse zuweisen Komponenten zur Laufzeit erzeugen 17.5.1 Steuerelemente 17.5.2 Menüs*
Zusammenfassung Übung
11
Inhaltsverzeichnis
•
19.2.5 Einen eigenen Listener implementieren 342 19.2.6 Kommunikation mit dem Debugger 346
19.3 Zusammenfassung 346 2 0 Delegates & Events 3 4 7
20.1 Delegates 347 20.1.1 Deklaration eines Delegate 347
20.2 Ereignisse 351 20.2.1 Ereignisinformationen definieren 352
20.2.2 Ereignisauslösende Klasse & Delegate 353 20.2.3 Das Ereignisobjekt definieren 354 20.2.4 Die Ereignisbehandlungsroutine 354 20.2.5 Klasse mit dem Abonnenten erstellen 355 20.2.6 Callback-Funktion des Abonnenten 356 20.2.7 Die Callback-Methode anmelden 356
20.2.8 Abschlussarbeiten 357 20.2.9 Die Testklasse bauen 359 20.2.10 Das große Ganze 359 20.3 Zusammenfassung 362
Reference - Teil III 363
21 Garbage Collection %. 365
21.1 Grundlagen 365 21.1.1 Die alte Welt - Reference Counting 366
21.1.2 DieneueWelt-GarbageCollectionin.NET 366
21.2 Finalize, Dispose, Close oder was? 367 21.2.1 Konzepte für die Freigabe von Objekten 367
21.2.2 Sichere Speicherfreigabe mit using 368
21.3 GC-Generationen 371 21.4 Die Garbage Collection steuern 371
21.5 Weitere Methoden der Klasse GC 373 21.5.1 Finalisierungen unterdrücken 373 21.5.2 Destruktoren doch wieder ausführen 374 21.5.3 Objekte am Leben erhalten 375
21.6 Zusammenfassung 375 22 Reflection in C# 377
22.1 Type, GetTypeO und typeofO 377 22.1.1 Die Beispielklasse 378 22.1.2 Her mit dem Typ: das Type-Objekt 379
22.1.3 Members only - Klassenmitglieder auflisten 379
22.1.4 Parameter fischen 381 22.1.5 Aktivieren - Dynamischer Methodenaufruf 383
12
Inhaltsverzeichnis
22.2 Reflection überzeugend demonstriert 384 22.2.1 Die Problemstellung 384 22.2.2 Der Lösungsansatz 385
22.3 Zusammenfassung 388
23 Attribute 391 23.1 Grundlagen 391 23.2 Vordefinierte Attribute 392
23.3 Was passiert bei der Benutzung eines Attributes? 395
23.4 Benutzerdefinierte Attribute 395 23.4.1 Definition der Attributklasse 395
23.4.2 Das Attribut AttributeUsageAttribute 396 23.4.3 Optionale Parameter in eigenen Attributen 398
23.5 Abrufen von Attributinformationen 399 23.5.1 Abfragen eines Attributes 400 23.5.2 Abrufen der Informationen mit Reflection 400
23.5.3 Feststellen, ob ein Attribut definiert ist 401
23.6 Zusammenfassung 402 24 Überladen von Operatoren 403
24.1 Wie funktioniert Operatorüberladung? 403 24.2 Was kann überladen werden? 404
24.2.1 Unäre Operatoren 404 24.2.2 Binäre Operatoren 405 24.2.3 Relationale Operatoren 405 24.2.4 Ein Beispiel zur Operatorüberladung 406
24.2.5 Überladen oder nicht überladen? 408
24.3 Zusammenfassung 409 25 Serialisierung « 411
25.1 Attribute oder ISerializable? 411
25.2 Die Beispielklasse 412 25.3 Attributgesteuerte Serialisierung 413
25.3.1 Serializable und NonSerialized 413
25.3.2 Formatter-Klassen 414 25.3.3 Der Prozess der Serialisierung 415
25.3.4 Deserialisierung 417 25.4 ISerializable implementieren 422 25.5 XML-Serialisierung 424
25.5.1 Die Beispielklasse 425 25.5.2 Serialisierung in eine XML-Datei 426
25.5.3 Deserialisierung aus einer XML-Datei 427 25.5.4 Steuerung der XML-Serialisierung 428
25.6 Zusammenfassung 429 - •
13
SSgl Inhaltsverzeichnis
•
26 Assemblies 431 26.1 Die Probleme der Vergangenheit 431
26.2 Was sind Assemblies? 432 26.2.1 Private und öffentliche Assemblies 434
26.2.2 Assemblies angucken 436 26.3 Öffentliche Assemblies erstellen 437 26.3.1 Der prinzipielle Ablauf 437 26.3.2 Beispiel-Bibliothek erstellen 437 26.3.3 Schlüsselpaar erzeugen 438 26.3.4 Signieren des Assemblies 438 26.3.5 Der globale Assembly-Cache 441 26.3.6 Assembly im CAC eintragen 442 26.4 Öffentliche Assemblies benutzen 444 26.5 Versionsverwaltung bei Assemblies 446
26.5.1 Aufbau der Versionsnummern 446 26.6 Informationen im Programm abrufen 447
26.7 Konfigurationsdateien 448 26.8 Zusammenfassung 454 27 Unsicherer Code 455
27.1 Zeiger in C# 455 27.2 Das Schlüsselwort unsafe 456
27.3 Nutzung von Zeigern 457 27.3.1 Deklaration von Zeigern 457
27.3.2 Zeiger-Operatoren 457 27.3.3 Beispiel für Zeigervariablen 458 27.3.4 Typumwandlungen von Zeigern 459 27.3.5 sizeof und Zeigerarithmetik 461
27.4 Der Operator -> 463 27.5 Zusammenfassung 464 28 XML-Dokumentation 465 28.1 XML-Kommentare 465
28.1.1 Eingabe von XML-Kommentaren 466 28.1.2 Unterstützte XML-Elemente 467 28.1.3 Generieren der Dokumentationdatei 468 28.1.4 Syntaxprüfung des Elementinhaltes 471
28.2 Zusammenfassung 472 29 Lösungen zu den Übungen 473
29.1 Kapitel 4 473 29.1.1 Die Fragen 473
29.1.2 Die Antworten 473
29.2 Kapitel 5 474 29.2.1 Die Fragen 474
29.2.2 Die Antworten 474
14
lO
.c c
•f5
B
<U
>
I/) ra x c
N O N O V O O O O O O O O N O N O I — I— i— ( N f N P M ' < r T j - ' ^ - i O i O U - ) r N r v r v O N O N O N O N O N O O O O P N | f N P M
i x i x r x r - v r v r ^ t v r v o o o o o o o o o o o o M o o o o o o o o o o o o o o o o o o o o o o o o o o o o o N O N O N O N O N O N O N m
5
m r o r o v o v o i v o o O N
O N O N O N O N O N O N O N O N
NO
3
•Q.(0
"1 ON fN
c
s.
2
£ 0)
5
«
ON f N
rten
S
oc
<
01 QPM ro
ON PM
t v
3
•5.ra
ON PM
C
&
i 2
OJ
b
*-:
• ^ ON f N
rten
I
oc
<
oih
PM
•<t ON PM
00
3
a.XL ra
"0
ON PM
c CT, 2
LL.
UJ
b
r"1
•o ON PM
rten
o
s
c<
(LI QPM uS
ON PM
ON
3
'5.ra
ON PM
C 0 1 CT)
ra uZ m
5
r—
NO ON PM
rten
o
1
c<
o>b
PM vq
ON PM
O
3
•5.ra
^
^
ON PM c CT, 2£ 01
b
T—
s
ON f N
rten
o
|
c<
Ol OPM rv ON PM
^ 3
•Q.ra
•
ON PMc
|
2£ Ol
b
*"\
°°.
ON PM
rten
1
oc
<
Ol5
PM 00 ON PM
PM
3
ara
ON PM
s &
2 u.
0) Q
'"".
<*.
ON PM
rten
s
o c<
0)b
PM ON ON PM
CO
3
QLra
ON PM
£ o , 2
LL.
Ol
b
6
^
ON PM
rten
o
1
c<
01b
PM Ö
*~
ON PM
"t
3
•Q.re
^
ON fN
c
1
2 LL.
Ol
5
r J r- ON PM
rten
o
1
c<
Olh
PM r-'
*~
ON PM
UO
3
' 5 . it rePM
ON1
PM
£
1
2 u.
0)
b
^
PM
"~;
ON PM
rten
1
oc
<
o>b
PM PM
*-;
ON PM NO
3 •a
raro ol PM
F,
1
2
LL.
Ol Q
ro
« I
ON PM
rten
1
oc
<
01b
fN ro
•—, ON PM
I V
3
•5.ra
^
"*
ON PM
C Ol CT)
ra LL.
0) Q
• * '
*-;
ON PM
rten
o
I
c<
01 QPM
•*r
*—,
ON PM
kzeuge r Compil
u 01
a» u o O ro
rundlagen
O
-.
ö ro C Ol
c
D .
ompiler-O
U
PM r—
d ro
2
-o
3
ILDASM
PM Ö ro
DASM
—J
,2.1
o ro
erfläche ie GUI-Ob
o
2.2
o ro
IL-Codes nzeige des
<
2.3
o ro
5
CO
ILA
ro
d ro
o
mInhaltsverzeichnis
•
30.4 Debugger 499 30.4.1 Aufruf des Debuggers 499
30.4.2 Die Kommandos 500
30.5 WinCV 502 30.6 VisualStudio.NET 503
30.7 Zusammenfassung 503
»
31 Referenzteil 505 31.1 Datentypen 505
31.1.1 Werttypen 505 31.1.2 Implizite Typumwandlungen 506
31.1.3 Referenztypen 507
31.2 Anweisungen 509 31.2.1 Auswahlanweisungen 509
31.2.2 Schleifenanweisungen 510 510
511 511 512
31.3 Präprozessorkommandos 513 513
514 514 515 515
31.4 Namensräume 515 515
515
31.5 Vordefinierte Attribute 519 Stichwortverzeichnis 523
31.2.3 31.2.4 31.2.5 31.2.6
Verzweigungsanweisungen Fehlerbehandlung Codeausführung Namensraumnutzung Präprozessorkommandos 31.3.1
31.3.2 31.3.3 31.3.4 31.3.5
#if, #else, elif, endif
#define, #undef
#warning, #error
#line
#region, #endregion Namensräume
31.4.1 31.4.2
MS-spezifische Namensräume .NET-Namensräume
Vordefinierte Attribute