296

C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

  • Upload
    others

  • View
    12

  • Download
    0

Embed Size (px)

Citation preview

Page 1: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2
Page 2: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2
Page 3: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

Patrick A. Lorenz

Programmierung im .NET Frameworkmit der C# Beta 2

C# Shortcut

Page 4: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

Der AutorPatrick A. LorenzProjektleiter Internet, combit GmbH, Konstanz, www.combit.net

http://www.hanser.de

Alle in diesem Buch enthaltenen Informationen wurden nach bestem Wissen zusammengestelltund mit Sorgfalt getestet. Dennoch sind Fehler nicht ganz auszuschließen. Aus diesem Grund sinddie im vorliegenden Buch enthaltenen Informationen mit keiner Verpflichtung oder Garantieirgendeiner Art verbunden. Autor und Verlag übernehmen infolgedessen keine Verantwortungund werden keine daraus folgende oder sonstige Haftung übernehmen, die auf irgendeine Art aus derBenutzung dieser Informationen – oder Teilen davon – entsteht, auch nicht für die Verletzung vonPatentrechten, die daraus resultieren können.

Ebenso wenig übernehmen Autor und Verlag die Gewähr dafür, dass die beschriebenen Verfahrenusw. frei von Schutzrechten Dritter sind. Die Wiedergabe von Gebrauchsnamen, Handelsnamen,Warenbezeichnungen usw. in diesem Werk berechtigt also auch ohne besondere Kennzeichnung nichtzu der Annahme, dass solche Namen im Sinne der Warenzeichen- und Markenschutz-Gesetzgebungals frei zu betrachten wären und daher von jedermann benutzt werden dürften.

Die Deutsche Bibliothek – CIP-Einheitsaufnahme

Ein Titeldatensatz für diese Publikationist bei Der Deutschen Bibliothek erhältlich.

Dieses Werk ist urheberrechtlich geschützt.Alle Rechte, auch die der Übersetzung, des Nachdruckes und der Vervielfältigung des Buches,oder Teilen daraus, vorbehalten. Kein Teil des Werkes darf ohne schriftliche Genehmigung desVerlages in irgendeiner Form (Fotokopie, Mikrofilm oder ein anderes Verfahren), auch nicht fürZwecke der Unterrichtsgestaltung, reproduziert oder unter Verwendung elektronischer Systemeverarbeitet, vervielfältigt oder verbreitet werden.

© 2002 Carl Hanser Verlag München WienGesamtlektorat: Fernando SchneiderCopy-editing: Manfred Sommer, MünchenHerstellung: Monika KrausUmschlaggestaltung: Büro für Text und Gestaltung herbert und herbertsfrau, AugsburgDatenbelichtung, Druck und Bindung: Kösel, KemptenPrinted in Germany

ISBN 3-446-21959-5

Page 5: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

Inhalt

1 Einführung............................................................................................................... 13

1.1 Wer sollte dieses Buch lesen? ................................................................................... 131.2 Was Sie brauchen ...................................................................................................... 141.3 Warum eine neue Sprache? ....................................................................................... 141.4 Das .NET Framework................................................................................................ 15

1.4.1 Installation der Beta 2.................................................................................. 161.5 Die Beispiele aus dem Buch...................................................................................... 18

1.5.1 Beispiele kompilieren .................................................................................. 181.5.2 Editoren ....................................................................................................... 18

1.6 Kontakt zum Autor.................................................................................................... 22

2 Erste Schritte in C# ................................................................................................. 25

2.1 Notation..................................................................................................................... 252.2 GROSS oder klein? ................................................................................................... 262.3 Variablen................................................................................................................... 272.4 Konstanten ................................................................................................................ 282.5 Einfache Datentypen ................................................................................................. 282.6 Einfache Datentyp-Konvertierung............................................................................. 292.7 Kommentare.............................................................................................................. 302.8 Namespaces............................................................................................................... 302.9 Konsolen-Applikationen ........................................................................................... 332.10 Die Methode Main .................................................................................................... 342.11 Hallo Welt ................................................................................................................. 35

3 Klassen & objektorientierte Programmierung – Teil I ........................................ 39

3.1 Was ist ein Objekt? ................................................................................................... 393.2 Was ist eine Klasse?.................................................................................................. 403.3 Instanziierung einer Klasse........................................................................................ 413.4 Terminierung eines Objekts ...................................................................................... 423.5 Deklaration einer neuen Klasse ................................................................................. 43

Page 6: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

6 _________________________________________________________________ Inhalt

3.5.1 Dynamisch versus statisch........................................................................... 463.5.2 Eigenschaften deklarieren............................................................................ 483.5.3 Methoden deklarieren .................................................................................. 533.5.4 Ereignisse deklarieren.................................................................................. 563.5.5 Das Schlüsselwort this................................................................................. 623.5.6 Modifikatoren.............................................................................................. 633.5.7 Konstruktor.................................................................................................. 673.5.8 Destruktor.................................................................................................... 723.5.9 Attribute ...................................................................................................... 74

4 Bedingungen ............................................................................................................ 79

4.1 Das if-Konstrukt........................................................................................................ 794.2 Das switch-Konstrukt................................................................................................ 824.3 Bedingungsoperator .................................................................................................. 86

5 Schleifen ................................................................................................................... 89

5.1 Die for-Schleife ......................................................................................................... 895.2 Die while-Schleife..................................................................................................... 915.3 Die do-Schleife ......................................................................................................... 925.4 Die foreach..in-Schleife............................................................................................. 925.5 Die Anweisungen break und continue....................................................................... 94

6 Sprunganweisungen ................................................................................................ 99

6.1 break.......................................................................................................................... 996.2 continue..................................................................................................................... 996.3 goto ......................................................................................................................... 1006.4 return....................................................................................................................... 1016.5 throw ....................................................................................................................... 102

7 Operatoren............................................................................................................. 105

7.1 Mathematische Standard-Operatoren ...................................................................... 1057.2 Mathematische Kurz-Operatoren ............................................................................ 1087.3 Zuweisungsoperatoren ............................................................................................ 1107.4 Noch mehr Mathematik mit der Klasse System.Math ............................................. 1127.5 Logische Operatoren ............................................................................................... 115

7.5.1 Vergleichsoperatoren................................................................................. 1157.5.2 Verknüpfungsoperatoren ........................................................................... 1167.5.3 Negationsoperator...................................................................................... 1187.5.4 Bitweise (binäre) Operatoren..................................................................... 118

7.6 Typenoperatoren ..................................................................................................... 123

Page 7: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

Inhalt _________________________________________________________________ 7

7.6.1 typeof......................................................................................................... 1237.6.2 is ................................................................................................................ 1267.6.3 as................................................................................................................ 1277.6.4 is versus as................................................................................................. 128

8 Arbeiten mit Zeichenketten .................................................................................. 131

8.1 Der Datentyp string ................................................................................................. 1318.1.1 Einfache Zuweisungen............................................................................... 1318.1.2 Escape-Zeichen.......................................................................................... 1328.1.3 Formatierungen.......................................................................................... 1348.1.4 String-Eigenschaften ................................................................................. 1368.1.5 Weitere String-Operationen....................................................................... 138

8.2 Die Klasse StringBuilder......................................................................................... 1488.2.1 StringBuilder-Eigenschaften...................................................................... 1498.2.2 StringBuilder-Methoden ............................................................................ 150

8.3 Reguläre Ausdrücke ................................................................................................ 1528.3.1 Der Aufbau von regulären Ausdrücken ..................................................... 1538.3.2 Die Klasse Regex....................................................................................... 1578.3.3 Die Regex-Optionen .................................................................................. 1648.3.4 Erweiterte Parsing-Möglichkeiten ............................................................. 166

9 Erweiterte Datentypen .......................................................................................... 171

9.1 Arrays...................................................................................................................... 1719.1.1 Initialisierung und Zugriff auf Arrays........................................................ 1719.1.2 Mehrdimensionale Arrays ......................................................................... 1749.1.3 Eigenschaften und Methoden der Array-Klasse ........................................ 177

9.2 Collections .............................................................................................................. 1819.2.1 ArrayList ................................................................................................... 1829.2.2 Hashtable ................................................................................................... 1839.2.3 Queue ........................................................................................................ 1859.2.4 SortedList .................................................................................................. 1879.2.5 Stack .......................................................................................................... 188

9.3 Strukturen................................................................................................................ 1899.4 Aufzählungen .......................................................................................................... 192

9.4.1 Standard-Aufzählungen ............................................................................. 1929.4.2 Flag-Aufzählungen .................................................................................... 194

10 Konvertierungen.................................................................................................... 199

10.1 Konvertierung von numerischen Werten................................................................. 19910.2 Konvertierung zu string........................................................................................... 201

Page 8: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

8 _________________________________________________________________ Inhalt

10.3 Konvertierung von Verweistypen............................................................................ 20410.4 Die Klasse Convert ................................................................................................. 209

11 Fehlerbehandlung ................................................................................................. 217

11.1 Was ist eine Ausnahme? ......................................................................................... 21711.2 Das try..catch..finally-Konstrukt ............................................................................. 21911.3 Die Klasse Exception .............................................................................................. 22311.4 Ausnahmen auslösen............................................................................................... 22511.5 Ausnahmen (kontrolliert) weiterreichen.................................................................. 22811.6 Eigene Ausnahmen definieren................................................................................. 23011.7 Zusammenfassung................................................................................................... 234

12 Klassen & objektorientierte Programmierung – Teil II..................................... 237

12.1 Überladungen .......................................................................................................... 23712.2 Vererbung ............................................................................................................... 241

12.2.1 Einfache Vererbungen ............................................................................... 24212.2.2 Überschreiben von Klassen-Mitgliedern ................................................... 24412.2.3 Verbergen von Klassen-Mitgliedern.......................................................... 24712.2.4 Konstruktoren und die Vererbung ............................................................. 24812.2.5 Klassen versiegeln ..................................................................................... 25212.2.6 Abstrakte Klassen...................................................................................... 253

12.3 Schnittstellen ........................................................................................................... 25612.3.1 Deklaration einer Schnittstelle................................................................... 25612.3.2 Implementierung einer Schnittstelle .......................................................... 25712.3.3 Noch ein tierisches Beispiel....................................................................... 25712.3.4 Mehrere gleichnamige Schnittstellen-Mitglieder....................................... 261

12.4 Benutzerdefinierte Operatoren erstellen .................................................................. 26212.4.1 Arithmetische Operatoren.......................................................................... 26212.4.2 Vergleichsoperatoren................................................................................. 26612.4.3 Konvertierungsoperatoren ......................................................................... 270

13 Weitergehende Programmierung......................................................................... 277

13.1 Arbeiten mit Threads............................................................................................... 27713.2 Reflections .............................................................................................................. 281

13.2.1 Eine Eigenschaft dynamisch abfragen ....................................................... 28113.2.2 Eine Methode dynamisch aufrufen ............................................................ 28213.2.3 Eine Methode mit Parametern dynamisch aufrufen................................... 28313.2.4 Alle Eigenschaften und Methoden auflisten .............................................. 284

13.3 Arbeiten mit dem CodeDOM.................................................................................. 28613.3.1 Ein Programm dynamisch erstellen ........................................................... 286

Page 9: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

Vorwort

Eigentlich hatte ich gar nicht vor, mich derart intensiv mit C# zu beschäftigen. DasThema war ursprünglich ein anderes. Doch wie jeder, der sich mit dem .NETFramework beschäftigt, bin auch ich nicht um die neue Sprache C#herumgekommen. Was also anfänglich nur als eine grobe Übersicht geplant war,hat sich sehr schnell zu einer ausführlichen Einführung in das Flaggschiff der .NET-Sprachen entwickelt. Ich bin mit dieser Entwicklung durchaus zufrieden, denn ohnediesen Ausflug würden Sie heute nicht das erste deutschsprachige Buch zur .NETund zur C# Beta 2 in den Händen halten.C# ist eine völlig neue Sprache, die mit dem ungeheuren Potenzial einesWeltkonzerns daherkommt. Das erlebt man nicht alle Tage, und ich persönlich habedie Entwicklung und die teilweise heftigen Diskussionen der vergangenen knapp 12Monate mit Interesse und Spannung verfolgt. Wer als Windows-Entwickler am Ballder Zeit bleiben will, wird sich mit .NET und C# auseinandersetzen müssen. Undwenn diese neue Vision von Microsoft Ihr Berufsleben nicht heute beeinflusst, dannsicherlich morgen.C# vereint die herausragenden Merkmale der aktuellen Microsoft Pro-grammiersprachen Visual C++ und Visual Basic. Die Kombination dieserbeiden Sprachen in Verbindung mit einem standardisierten Klassen-Framework istsinnvoll und wird es Ihnen als Entwickler leichter machen, Anwendungen fürverschiedene Umgebungen wie Desktop, Internet oder gar mobile Systeme zuentwickeln. Auch die Arbeit im Team wird letztlich durch das Zusammenrückender Sprachen viel einfacher und effektiver.Wenn Sie dieses Buch gekauft haben, dann sind Sie vermutlich oder hoffentlich aneiner ganz neuen Sprache interessiert. Eine Sprache mit dem Potenzial, andereSprachen vielleicht nicht völlig, zumindest aber in den Hauptbereichen derEntwicklung zu verdrängen. Sie tun daher gut daran, sich mit diesem Buch einenÜberblick zu verschaffen. Wenn Sie bereits mit Sprachen wie C, C++ oder Javagearbeitet haben, wird Ihnen jedenfalls die Syntax bekannt vorkommen. Dennochgibt es viel Neues zu lesen und zu lernen. Die Kenntnisse verschiedener Konzepteum .NET sind zum Verständnis der Sprache einfach unerlässlich.

Page 10: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

10 _____________________________________________________________ Vorwort

Dieses Buch soll sowohl erfahrenen Entwicklern als auch Einsteigern mit ehergeringen Programmiererfahrungen ein kompakter, aber dennoch umfassenderEinstieg in die Sprache C# sein. Ich habe mich bemüht, alle wesentlichen Aspekteklar gegliedert zusammenzufassen. Die vielen Beispiele, die auf der bucheigenenWebsite zum Download zur Verfügung stehen, vereinfachen den praktischenEinstieg in die Sprache. Die sprachorientierte Gliederung ermöglicht zudem dieVerwendung als Nachschlagewerk und Referenz, wann immer Sie bei der ArbeitUnterstützung benötigen.Sie halten mit diesem Buch mein Erstlingswerk in den Händen. Es ist mir dahersehr wichtig, Ihre Meinung zu hören. Nehmen Sie dieses Angebot bitte wahr undschreiben Sie mir, wann immer Sie etwas zu diesem Buch loswerden möchten. DieE-Mail-Adresse sowie die URL der bereits angesprochenen Website finden Sie inder Einführung weiter unten. Ein zweites Buch, das sich ebenfalls mit demThemenkomplex .NET auseinandersetzt, ist übrigens bereits in Arbeit und wirdvoraussichtlich Anfang 2002 nach dem Release von .NET erscheinen. WeitereInformationen hierzu finden Sie zu gegebener Zeit ebenfalls auf der Website zumBuch.Ich möchte an dieser Stelle nicht versäumen, einige Dankesworte an diejenigen zurichten, die dieses Projekt ermöglicht haben. Mein Dank gilt meinem LektorFernando Schneider, der mich quasi entdeckt und vom Fleck weg engagiert hat. Erist an die Zusammenarbeit sicherlich nicht blauäugig, aber doch mit sehr vielVertrauen herangegangen und hat dafür meinen Respekt verdient. Ich möchte auchmeinem Arbeitgeber, der combit GmbH, danken, dass Sie es mir ermöglicht haben,neben meiner regulären Arbeit an diesem Buch zu werkeln. Einen besonderen Dankund einen lieben Gruß möchte ich an meine Familie richten. Neben meiner Mutterund meinen Großeltern sind es nicht zuletzt auch meine Katzen Filou und Shari, diemich motiviert und inspiriert haben. Sie werden im Laufe des Buches verstehen,was ich meine. Viele Grüße übrigens auch an Mr. Jingles; die Cineasten unter Ihnenwissen, wen ich meine.Es bleibt mir, Ihnen viel Spaß an der Lektüre dieses Buches und viel Erfolg bei derArbeit mit .NET und C# zu wünschen.

Patrick A. LorenzKonstanz, im Oktober 2001

Page 11: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

1Einführung

Wer sollte dieses Buch lesen?

Was Sie brauchen

Warum eine neue Sprache?

Das .NET Framework

Die Beispiele aus dem Buch

Kontakt zum Autoren

Page 12: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

12 ____________________________________________________________________

Inhaltsübersicht Kapitel 1

1 Einführung .........................................................................................................13

1.1 Wer sollte dieses Buch lesen?..............................................................................131.2 Was Sie brauchen ................................................................................................141.3 Warum eine neue Sprache? .................................................................................141.4 Das .NET Framework..........................................................................................151.4.1 Installation der Beta 2..........................................................................................161.5 Die Beispiele aus dem Buch ................................................................................181.5.1 Beispiele kompilieren ..........................................................................................181.5.2 Editoren ...............................................................................................................181.6 Kontakt zum Autor ..............................................................................................22

Page 13: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

____________________________________________________________________ 13

1 Einführung

Wie sage ich eigentlich C#? Obwohl es mittlerweile vermutlich hinlänglich bekanntist, darf die Sprechweise von C# an erster Stelle dieses Kapitels nicht fehlen. C#wird „C Sharp“ gesprochen. Sharp ist Englisch und bedeutet übersetzt scharf, starkoder durchdringend. „C Scharf“ hört sich eigentlich ganz nett an und trifft den Kernin der Übersetzung vermutlich am ehesten.

1.1 Wer sollte dieses Buch lesen?

Würde die Frage lauten, wer das Buch kaufen soll, würde ich antworten:„Möglichst viele“. Aber das war nicht die Frage und insofern möchte ich etwasdifferenzierter antworten. C# ist sicherlich die kommende Programmiersprache,wenn es um die Entwicklung im Windows-Umfeld geht. Natürlich werden auchandere Sprachen neben C# existieren, aber diese werden durch das .NETFramework viele typische Eigenschaften verlieren. Letztlich bleibt den Sprachendie Syntax und die Semantik. Das ist nicht viel, gerade wenn man bedenkt, dass C#optimal auf das .NET Framework abgestimmt ist. Es spricht also einiges für C# undsomit auch dieses Buch zu lesen.Wer also sollte es lesen? Jeder, der über ein wenig Programmier-Erfahrung verfügtund eine komplett neue Sprache bereits vor dem Erscheinen kennen lernen möchte.Visual Basic-Entwickler lernen die Möglichkeiten einer optimierten Syntax kennenund C++ oder Java-Entwickler werden sehen, dass vieles geblieben ist sich aberauch Vieles geändert hat. Zum Besseren, wohl gemerkt. Wenn es Sie alsointeressiert, die Geburt einer Sprache im Jahre 2002 zu erleben, gespickt mitHintergrundwissen und der Möglichkeit, die Sprache vom Start weg benutzen zukönnen, dann sind Sie hier richtig.

Page 14: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

14 _________________________________________________ 1.2 Was Sie brauchen

1.2 Was Sie brauchen

In erster Linie Spaß am Lesen! Die richtige Technik natürlich, insbesondere wennSie die Programmbeispiele des Buches gleich ausprobieren wollen. Sie benötigendas .NET Framework in der zur Drucklegung aktuellen Beta Version 2. DasFramework läuft unter Windows 2000 oder XP und reicht im Grunde schon aus. Siesollten sich allerdings auch Gedanken über einen Editor machen. EinigeMöglichkeiten finden Sie weiter unten in diesem Kapitel. Eine gute Möglichkeit istdie Visual Studio.NET Entwicklungsumgebung. Wenn Sie die Beta-Version desFrameworks auf CD erhalten haben, sollte die Beta von Visual Studio ebenfallsmitgeliefert worden sein.

1.3 Warum eine neue Sprache?

Die bereits bestehenden Sprachen des .NET Frameworks Visual C++, VisualBasic.NET und JScript, haben allesamt schon einige Jahre auf dem Buckel.Dementsprechend haben sich bestimmte Befehle und Schreibweisen quasihistorisch entwickelt. Diese Sprachen konsequent und ausschließlich auf dieVisionen und Konzepte des .NET Frameworks umzuschreiben, würde zu einemradikalen Bruch mit den vergangenen Versionen führen. Auch wenn beispielsweiseim Falle von Visual Basic.NET schon so keine vollständige Kompatibilität besteht,so wurden doch viele Kompromisse geschlossen, die es Entwicklern erleichtern,bestehenden Code auf .NET umzuschreiben.„Wenn Du nicht vorwärts gehen kannst, gehe rückwärts!“ Es gibt ganz bestimmtein altes japanisches Sprichwort, das so oder so ähnlich lautet. Vielleicht finden Siees ja auf Ihrem nächsten Glückskeks. Genau diesem Spruch ist Microsoft gefolgt.Wenn sich die bestehenden Sprachen also nicht ohne weiteres konsequent an dem.NET Framework ausrichten lassen, dann schreiben wir eben eine neue Sprache.Diese neue Sprache heißt C# und ist als Folge aus der Entwicklungsidee absolutkonsequent auf .NET ausgerichtet. Das Framework, aber auch die Sprache C#vereinen die Erfahrungen und Vorteile der bisherigen Sprachen undEntwicklungswerkzeuge. Ich persönliche sehe in C# die Kombination derleistungsfähigen Syntax von (Visual) C++ und der intuitiven Einfachheit von VisualBasic. Eine gelungene Kombination sowohl für erfahrene Entwickler als auchNeueinsteiger. Letztlich wird es in meinen Augen auch dieses Argument sein, dasder Sprache C# gegenüber anderen eine nachhaltig bessere Position undVerbreitung sichern wird. Eine weitere Konsequenz sehe ich im langfristigenWegfall von Visual Basic. Nicht, dass ich etwas gegen diese Sprache habe, ich binja beinahe damit „aufgewachsen“, aber sie wird durch C# im Grunde überflüssig.

Page 15: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

1 Einführung ___________________________________________________________15

Nebenbei bemerkt mag ein nicht zu vernachlässigendes Argument für dieEntwicklung von C# auch der Wegfall von Visual J++ gewesen sein. Demewigwährenden Streit zwischen Microsoft und Sun sei Dank. Doch zu diesemPunkt hat sich Microsoft meines Wissens (noch) nicht geäußert.

1.4 Das .NET Framework

Seit Mitte 2000 versucht Microsoft ungehemmt, allen Entwicklern und solchen, diees noch werden wollen, eine neue Philosophie unterzujubeln: „Empower peoplethrough great software, any time, any place and on any device“ Der Slogan löst denbisherigen – „Information at your fingertips“ – ab. Warum? Die Frage ist eigentlichganz einfach zu beantworten: Die alte Vision hat sich erfüllt, unter jedemSchreibtisch steht ein PC und der Zugriff auf das Internet ist auch schon für so gutwie alle eine Selbstverständlichkeit.Das Produkt, das die neue Vision mit Leben füllen soll, nennt sich Microsoft .NET.Die Bezeichnung „Produkt“ ist in diesem Zusammenhang vielleicht etwasirreführend, denn .NET ist eigentlich kein solches, sondern eine einheitliche Basisfür Entwicklungen unter Windows und möglicherweise später auch anderenBetriebssystemen.Microsoft .NET, auch .NET Framework genannt, ist in der Vergangenheit von derFachpresse oft als größte Revolution nach der Umstellung von DOS auf Windowsbezeichnet worden. Für Entwickler mag dies zustimmen und entsprechend heftigsind die Diskussionen in den populären Newsgroups und Fachtagungen. Die einenstimmen der neuen Philosophie zu und sehen mit ihr viele alltägliche Problemeeines Entwicklers gelöst. Andere weisen auf Inkompatibilitäten zu bestehendenEntwicklungen hin und sehen durch diese ihre Existenz gefährdet. Letztlich mussjeder sich hier selbst eine Meinung bilden. Eines steht jedoch fest: Kein Windows-Entwickler wird an .NET vorbeikommen, dafür wird Microsoft sorgen. Seien Siealso vorbereitet, bevor Sie die Welle unerwartet überrennt.Betrachtet man .NET distanziert, erkennt man sehr schnell dessen Grundidee.Jegliche Funktionalität wurde in ein einheitliches, hierarchischstrukturiertesFramework verpackt, das über einheitliche Schnittstellen anzusprechen ist. Diesbezieht sich allerdings nicht nur auf spezielle Windows-Funktionen, sondern gehtweiter, bis hin zur Programmiersprache. Die Funktionalität wurde auch hierherausgelöst und in eine allgemeine Common Language Runtime (CLR) gesteckt.Die einzelnen Sprachen wurden auf die individuelle Semantik sowie dieBefehlssyntax reduziert. Auf den ersten Blick klingt das albern, letztlich führt esjedoch nur Microsofts alte Idee eines Komponenten-basierten Systems eine Stufeweiter. Auch Aspekte wie Typensystem, Fehlermanagement, Debugging und vielesmehr werden einheitlich von der CLR beziehungsweise anderen Bereichen des

Page 16: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

16 _______________________________________________ 1.4 Das .NET Framework

.NET Frameworks übernommen. Auch an Punkten wie der Distribution vonKomponenten und der Versionsverwaltung wurde gearbeitet. Eine Registrierungvon Komponenten ist nicht mehr notwendig, ein einfaches File-Copy reicht völligaus. Verschiedene Versionen einer Komponente können so parallel verwendetwerden. Auch der leidige Neustart der Internet Information Services beiAktualisierungen von Internet-Komponenten entfällt dadurch beispielsweise.Eine einheitliche Zwischensprache löst nicht nur die Konkurrenz-Situation diverserProgrammiersprachen, sondern auch die Plattform-übergreifende Distribution vonProgrammen. Diese werden fortan von jeder .NET Sprache in die MicrosoftIntermediate Language (MSIL) kompiliert und anschließend verteilt. Auf demSystem des Kunden angekommen, werden die Programme beim ersten Aufruf inspezifischen Maschinencode umgesetzt. Hierfür sorgt der so genannte Just-In-Time-Compiler (JIT). Kennen Sie das etwa? Klar, Java und auch Teile von Windows CEmachen das nicht viel anders. Und auch Microsoft hat wohl schon über einePortierung von .NET auf Linux nachgedacht. Eine interessante Perspektive...Großartige Geschwindigkeitsverluste gegenüber reinem Maschinencode jetzigerProgrammiersprachen befürchtet Microsoft übrigens nicht. Schließlich sind dieaktuellen Rechnerkonfigurationen derart performant, dass die Unterschiede imBereich von Millisekunden liegen sollen. Wer also alle drei Monate einen neuenRechner kauft, wird voraussichtlich keine Probleme haben. Aber mal im Ernst, einernsthafter Unterschied ließ sich zumindest in meinem Test nicht feststellen.

1.4.1 Installation der Beta 2

Die mir vorliegende deutschsprachige Beta 2 kommt auf insgesamt fünf CD-ROMsdaher. Die ersten drei enthalten die Visual Studio.NET Entwicklungsumgebung mitden Sprachen C#, Visual C++ .NET, Visual Basic.NET und Visual FoxPro.NET.Die vierte mit „Windows Component Update“ betitelte CD enthält das eigentlicheFramework, also alles, was Sie zum Loslegen brauchen. Die fünfte und letzte CDenthält Visual Sourcesafe 6.0c.Zur Installation legen Sie die erste CD ein. Es erscheint der in der Abbildung 1.1gezeigte Dialog. Sie werden nun in drei Schritten zum Ziel geführt:

1. Windows Component Update2. Visual Studio.NET3. Service Releases

Page 17: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

1 Einführung ___________________________________________________________17

Der erste Punkt ist im Grunde der wichtigste. Sie werden aufgefordert, die vierteCD einzulegen, und diese enthält wie beschrieben das eigentliche .NET Framework.Ihr System wird auf Vordermann gebracht und enthält anschließend neben denbenötigten Komponenten auch das .NET Framework SDK mit allen erdenklichenHilfe-Informationen, Referenzen und Beispielen sowie die Compiler für C# undVisual Basic.NET.Sofern Sie sich für Visual Studio.NET als Entwicklungsumgebung entscheiden(siehe unten), kommt nun wieder die erste CD ins Laufwerk. Natürlich können Sieauswählen, welche Teile der Umgebung installiert werden sollen. Je nach Auswahlkommt hier schon das eine oder andere Gigabyte zusammen.Sofern Sie Visual Studio.NET installiert haben, sollten Sie unbedingt auch dendritten Punkt beachten und sich mit den aktuellsten Service Releases versorgen. Siebenötigen hierzu zwar einen Internet-Zugang und mitunter ein wenig Geduld, aberes ist wirklich notwendig. Einige früheren Versionen der Beta waren zeitlicheingeschränkt, und so könnte Ihnen die Vorfreude auf VS.NET ziemlich schnellvergehen.

Abbildung 1.1 In drei Schritten zum Ziel: Die Installation von .NET

Page 18: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

18 _________________________________________ 1.5 Die Beispiele aus dem Buch

1.5 Die Beispiele aus dem Buch

Alle im Buch vorgestellten Beispiele basieren auf der derzeit verfügbaren deutschen.NET Beta 2 und wurden mit dieser getestet. Aus Aktualitätsgründen habe ichdarauf verzichtet, die Beispiele auf eine beiliegende CD-ROM zu pressen. Natürlichsollen Sie trotzdem keinen neuen Weltrekord im Schnell-Tippen aufstellen. Siekönnen vielmehr ganz entspannt die zum Buch gehörende Website aufrufen undsich die Beispiele bequem herunterladen. Alles was Sie dazu brauchen, ist dieAdresse der Website und ein Passwort, das Sie als rechtmäßigen Käufer diesesBuches ausweist.

www.csharp-shortcut.dePasswort: XGHT5Z7T

Auf der Website plane ich auch, Informationen zur Verfügung zu stellen, die sichnach Drucklegung ergeben haben. Das ein oder andere Fehlerchen wird sich trotzgewissenhafter Arbeit und gründlicher Korrektur sicherlich eingeschlichen haben.Nützliche Links zum Thema sollen das Angebot schließlich abrunden.

1.5.1 Beispiele kompilieren

Apropos Beispiele... Wenn Sie diese ausprobieren wollen, dann benötigenselbstredend einen Compiler. Dieser kommt mit dem .NET Framework, das Siemittlerweile vielleicht schon installiert haben. Der Compiler kann entweder indirektdurch die Visual Studio.NET Entwicklungsumgebung oder direkt alsKonsolenapplikation aufgerufen werden. Der Compiler wird in diesem Fall unterdem Namen csc.exe gefolgt von der gewünschten C# Quellcode-Datei (.cs)aufgerufen. In der Regel reicht dies bereits aus, obwohl natürlich eine Reihe vonOptionen angeboten werden, die ausführlich bei Aufruf von csc.exe /? beschriebenwerden. Die Website enthält die Beispiele übrigens auch in kompilierter Form, Siekönnen sich diesen Schritt also gegebenenfalls zunächst einmal sparen.

1.5.2 Editoren

Zum Ausprobieren der Beispiele ist ein Editor nicht wirklich zu verachten.Verschiedene Alternativen stehen zur Verfügung. Ich möchte Ihnen einigevorstellen und meine ganz persönlichen Eindrücke vermitteln. Welche dervorgestellten Lösungen für Sie richtig sind oder ob eine nicht erwähnte Möglichkeitvielleicht viel besser ist, möchte ich Ihnen überlassen – die Anforderungenunterscheiden sich teilweise doch sehr deutlich.

Page 19: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

1 Einführung ___________________________________________________________19

Notepad

Lachen Sie bitte nicht, aber die Beispiele dieses Buches wurden allesamt mit demalten, ewig treuen und absturzsicheren Notepad entwickelt. Die Gründe hierfür sindallerdings weniger in einem sentimentalen Hang zu diesem Entwickler-Freund alsin der Schlankheit des Programms zu suchen. Für die meist relativ überschaubargehaltenen Beispiele reicht dieser Editor aus und bietet die notwendigeGrundfunktionalität. Auf jeglichen Komfort muss man allerdings zur Gänzeverzichten.Wenn Sie ähnlich wie ich über Notepad denken, dann mag der Einsatz zu überlegensein. Wer allerdings auf ein klein wenig Komfort bei der Arbeit nicht verzichtenmöchte und auf keinen Fall Zeile 38 manuell suchen möchte, der sollte sich an eineder folgenden Alternativen halten.

Abbildung 1.2 Lang lebe das Notepad!

Page 20: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

20 _________________________________________ 1.5 Die Beispiele aus dem Buch

Visual Studio.NET

Wie schon weiter oben erwähnt, wird die Beta der neuen Visual Studio.NETEntwicklungsumgebung gemeinsam mit der Beta des Frameworks ausgeliefert. DieIngesamt fünf CD-ROMs installieren auf Ihrem System eine ausgereifte und bereitsjetzt sehr stabile Plattform zur Entwicklung jeglicher .NET Plattform. Neben C#werden auch C++ und Visual Basic.NET unter einem Dach angeboten.Die Features sind den Erfahrungen der Vorgängerversionen entwachsen undmachen dem Namen EntwicklungsUMGEBUNG wirklich alle Ehre. Sie finden hierso ziemlich alles, was Sie zur Entwicklung benötigen unter einer einheitlichenOberfläche. Auch eine kleine Aufgabenverwaltung und das Framework SDK alsOnline-Hilfe wurden integriert.Wer ein komplettes und vollständiges Entwicklungssystem präferiert, der ist mitdem Visual Studio.NET sicher gut beraten. Die Abbildung zeigt den Editor, dieAufgabenverwaltung (unten) sowie den Projekt-Explorer (rechts). WeitereToolfenster blenden sich bei Bedarf ein und werden symbolisiert am Fensterdargestellt (rechts oben und unten links).

Abbildung 1.3 Überzeugt mit komfortablen Hilfsmitteln wie einer Aufgabenverwaltung undvielem mehr: Visual Studio.NET IDE Beta 2.

Page 21: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

1 Einführung ___________________________________________________________21

SharpDevelop

SharpDevelop ist vermutlich eines der ältesten und erfolgsreichsten, nichtkommerziellen Projekte, die bereits vollständig mit C# entwickelt wurden. DerEntwickler Mike Krüger (nein, nicht der mit der Nase und dem Holländer alsFreund) hat bereits im September 2000 (!) mit der Entwicklung begonnen.SharpDevelop ist ein C# Code-Editor mit zahlreichen nützlichen Features. Inmeinen Augen handelt es sich um eine echte Alternative zur Visual Studio.NETEntwicklungsumgebung.Das Projekt wird unter der GNU-Lizenz veröffentlicht und kommt daher optionalmit dem vollständigen Quellcode daher. Sie können den Editor auf diese Weisevollständig Ihren eigenen Wünschen anpassen und die Änderungen gegebenenfallsauch wieder veröffentlichen. Und selbst wenn Sie keine Änderungen vornehmenwollen, können Sie den Quellcode als Beispiel für das sehen, was mit C# möglichist. Hierfür spricht nicht zuletzt die sehr konsequente Umsetzung der .NET-Ideen.Zur Drucklegung dieses Buches war die Milestone Beta Version 0.75 aktuell. DieAbbildung zeigt diese Version im Einsatz. Die jeweils aktuelle Version finden Sieim Internet. Auf der Web-Site zum Buch unter www.csharp-shortcut.de finden Sieden jeweils aktuellen Download-Link.

Abbildung 1.4 SharDevelop ist eine echte und kostengünstige Alternative zu VisualStudio.NET.

Page 22: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

22 _________________________________________________ 1.6 Kontakt zum Autor

1.6 Kontakt zum Autor

Wenn Sie Glückwünsche, Lob oder BHs loswerden wollen, dann können Sie gerneKontakt mit mir aufnehmen. Sie erreichen mich unter

[email protected]

Falls Sie allerdings Fragen, Anregungen, Kritik oder gar Beschwerden haben, dannwenden Sie sich bitte an [email protected]. Nein, nein, keine Angst,selbstverständlich stelle ich mich Ihren Mails und freue mich über jeglicheskonstruktive Feedback zu diesem Buch. Mangels Zeit kann ich allerdings keineFragen beantworten, die ganz allgemein C# und nicht speziell dieses Buchbetreffen. Ich bitte hierfür um Verständnis. Ich werde versuchen, Links zuentsprechenden Foren und Newsgroups unter www.csharp-shortcut.de für Siebereitzuhalten.

Page 23: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

2Erste Schritte in C#

Notation

GROSS oder klein?

Variablen

Konstanten

Einfache Datentypen

Einfache Datentyp-Konvertierung

Kommentare

Namespaces

Konsolen-Applikationen

Die Methode Main

Hallo Welt

Page 24: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

24 ____________________________________________________________________

Inhaltsübersicht Kapitel 2

2 Erste Schritte in C# ...........................................................................................25

2.1 Notation ...............................................................................................................252.2 GROSS oder klein? .............................................................................................262.3 Variablen .............................................................................................................272.4 Konstanten...........................................................................................................282.5 Einfache Datentypen............................................................................................282.6 Einfache Datentyp-Konvertierung.......................................................................292.7 Kommentare ........................................................................................................302.8 Namespaces .........................................................................................................302.9 Konsolen-Applikationen......................................................................................332.10 Die Methode Main...............................................................................................342.11 Hallo Welt ...........................................................................................................35

Page 25: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

____________________________________________________________________ 25

2 Erste Schritte in C#

Das Verständnis dieses Kapitels erfordert grundlegende Programmierkenntnisse. Eswird nicht detailliert auf die einzelnen Aspekte der Programmierung, wohl aber aufderen Syntax in C# eingegangen. Sie müssen beispielsweise nicht wissen, wie eineif-Bedingung in C# formuliert wird, Sie müssen aber wissen, was eine solcheBedingung überhaupt ist.

2.1 Notation

• Befehle werden in C# Befehlszeilen-orientiert abgearbeitet. Das Ende einerBefehlszeile wird dabei nicht durch den Umbruch, sondern durch ein Semikolonmarkiert. Auf diese Weise kann sich eine Befehlszeile über mehrere reale Zeilenerstrecken oder können mehrere Befehlszeilen in einer realen Zeile notiertwerden.

Befehlszeile;

• Gültigkeitsbereiche werden mit geschweiften Klammern notiert. Zuvor wird daseinleitende Schlüsselwort notiert. Diesem Schlüsselwort folgt in diesem Fallkein (!) Semikolon. Alle Befehlszeilen, die sich innerhalb der Klammerungbefinden, zählen zum Gültigkeitsbereich des Schlüsselwortes.

Schlüsselwort{...}

Befehlszeilen

Gültigkeits-bereiche

Page 26: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

26 ________________________________________________ 2.2 GROSS oder klein?

Die im Gültigkeitsbereich notierten Befehlszeilen werden der Übersicht halbereingerückt. So ist eine gute Lesbarkeit gewährleistet.

Schlüsselwort{Befehlszeile1;Befehlszeile2;}

• Der Zugriff auf Mitglieder eines Objektes, wie dessen Eigenschaften undMethoden, erfolgt immer durch Trennung mit einem Punkt. AndereTrennzeichen wie beispielsweise in C++ sind nicht vorgesehen.

Objekt.Methode();Variable = Objekt.Eigenschaft;

• Parameter von Methodenaufrufen werden Komma-separiert in rundenKlammern hinter der Methode notiert. Werden keine Parameter angegeben,werden die runden Klammern dennoch (leer) notiert.

Methode(Parameter1, Parameter2)

• Der Zugriff auf Indexer erfolgt in eckigen Klammern:

Variable = Indexer[Index];

• Einzelne Zeichen werden in einfachen Anführungsstrichen notiert:

Variable = 'x';

• Zeichenketten werden in doppelten Anführungszeichen notiert:

Variable = "abc";

2.2 GROSS oder klein?

C# achtet auf die Groß-Klein-Schreibung und daher müssen Sie ebenfalls daraufachten. Die Sprache ist also casesensitive. Wenn Sie einen Befehl nicht ganzkorrekt notieren, wird dieser einfach als unbekannt zurückgewiesen. Die Variable...

Objekte

Parameter

Indexer

Zeichenketten

Page 27: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

2 Erste Schritte in C# ____________________________________________________27

variable

...ist nicht identisch mit...

Variable

Auch wenn es auf diese Weise möglich ist, zwei gleichnamige Variablen zuverwenden, die sich lediglich in der Goß-Klein-Schreibung unterscheiden, solltenSie dies unbedingt unterlassen. Dies würde unter Umständen zu einem sehrunübersichtlichen Programm führen und Sie würden sich so nicht wirklich einenGefallen tun.

2.3 Variablen

Variablen werden in C# in der folgenden Form deklariert:

Datentyp Variablenname;

Sollten mehrere Variablen vom selben Datentyp deklariert werden, werden diesedurch Kommata separiert:

Datentyp, Variablenname1, Variablenname2;

Möchte man der Variable direkt einen Wert zuweisen, ist dies bereits in der Zeileder Deklaration möglich.

Datentyp Variablenname = AndereVariable;

Möchte man hingegen eine neu instanziierte Variable zuweisen, wird dasSchlüsselwort new gefolgt vom Datentyp und runden Klammern verwendet.

Datentyp Variablenname = new Datentyp();

Um einen Datentyp neu zu instanziieren und direkt einen initiellen Wert zuübergeben, kann dieser als Parameter übergeben werden.

Datentyp Variablenname = new Datentyp(InitiellerWert);

Page 28: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

28 _______________________________________________________ 2.4 Konstanten

2.4 Konstanten

Konstanten werden wie Variablen definiert, es wird jedoch zu Beginn derBefehlszeile der Modifikator const notiert.

const Datentyp Konstantenname = Wert;

2.5 Einfache Datentypen

Das .NET Framework unterstützt eine ganze Reihe von unterschiedlichenDatentypen. In C# werden diese durch integrierte Datentypen angesprochen. Die inder folgenden Tabelle vorgestellten Datentypen sind Wertetypen, das heißt diesewerden direkt auf dem Stack abgelegt. Einzige Ausnahme bildet der Datentypstring, der einen Verweistyp darstellt und dessen Inhalt somit auf dem Heapabgelegt wird.

Tabelle 2.1 Einfache Datentypen in der Übersicht

Datentyp Bytes Beschreibung

byte 1 Byte ohne Vorzeichen

sbyte 1 Byte mit Vorzeichen

short 2 Short mit Vorzeichen (16 Bit)

ushort 2 Short ohne Vorzeichen (16 Bit)

int 4 Integer mit Vorzeichen (32 Bit)

uint 4 Integer ohne Vorzeichen (32 Bit)

long 8 Integer mit Vorzeichen (64 Bit)

ulong 8 Integer ohne Vorzeichen (64 Bit)

float 4 Gleitkommazahl (32 Bit)

double 8 Gleitkommazahl (64 Bit)

Decimal 12 Dezimalzahl mit hoher Genauigkeit (96 Bit)

bool 1 Bit Logischer Wert, ja oder nein, true oder false

char 2 Unicode-Zeichen

string 4 Unicode-Zeichenkette, Verweistyp

Page 29: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

2 Erste Schritte in C# ____________________________________________________29

2.6 Einfache Datentyp-Konvertierung

C# ist ein typensichere Sprache. Daher müssen Konvertierungen von einemDatentyp zu einem anderen meist explizit vorgenommen werden. ImpliziteKonvertierungen werden nur dann vom Compiler akzeptiert, wenn diese von denentsprechenden Datentypen unterstützt werden und sichergestellt ist, dass durch dieKonvertierung keine Datenverluste auftreten können Die implizite Konvertierungerfolgt durch bloße Zuweisung. Die explizite Konvertierung hingegen wird mitHilfe des folgenden Schemas realisiert:

NeueVariable = (NeuerDatentyp) AlteVariable;

Das folgende Beispiel konvertiert eine Variable vom Typ short implizit in denDatentyp int.

Listing 2.1 convert1.cs

short n1 = 15;int n2;

n2 = n1;

Console.WriteLine(n2.ToString());

Da int der größere Datentyp ist, kann ein short problemlos implizit konvertiertwerden, denn es können keine Datenverluste auftreten. Andersherum ist jedoch dieKonvertierung von short zu int nur explizit möglich. Hier können unter UmständenDatenverluste auftreten, da short der kleinere Datentyp ist.

Listing 2.2 convert2.cs

int n1 = 15;short n2;

n2 = (short) n1;

Console.WriteLine(n2.ToString());

Interessant ist auch die Verwendung der Methode ToString(). Die Methode wirdvon jedem (!) Objekt und somit auch von jeder Klasse unterstützt, da sie von derMutter aller Objekte geerbt wird.

ImpliziteKonvertierung

ExpliziteKonvertierung

Page 30: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

30 ______________________________________________________ 2.7 Kommentare

2.7 Kommentare

Kommentare lassen sich auf zwei unterschiedliche Arten einfügen. Um eine Zeile(nicht Befehlszeile) als Kommentar auszuweisen, werden an der gewünschten Stellezwei Slashs notiert. Alles, was innerhalb der Zeile nach diesen Zeichen steht, giltals Kommentar.

Anweisungen; // Kommentar

Um einen ganzen Bereich als Kommentar auszuweisen, wird dieser mit /* und */eingeklammert.

Anweisungen/* Anfang des KommentarsblablablaEnde des Kommentars */Anweisungen

2.8 Namespaces

Das .NET Framework gliedert die von ihm zur Verfügung gestellte Funktionalitätin einer Namens-Hierarchie. Innerhalb jeder Ebene dieser Hierarchie sind Elementewie Klassen hinterlegt. Die einzelnen Ebenen werden durch mit Punkten separierteNamen angesprochen. Man nennt eine einzelne Ebene Namespace. Ein typischerName für einen verschachtelten Namespace ist beispielsweise...

System.Windows.Forms

Der Zugriff auf die Elemente eines Namespace erfolgt durch Angabe desvollständigen Namespace-Namens und anschließend mit einem Punkt separat dasgewünschte Element. Der Zugriff auf die Ausgabe-Konsole sieht beispielsweise wiefolgt aus:

System.Console.WriteLine("Hallo Welt");

„System“ ist der Name des Namespace, „Console“ der Name der Klasse und„WriteLine“ die Methode zur Ausgabe des übergebenen Textes auf der Konsole.Alternativ können ein oder auch mehrere Namespaces direkt in das Programmeingebunden werden. Hierzu wird der Name des Namespace mit Hilfe des using-Schlüsselwortes zu Beginn des Programms notiert. Die Mitglieder des oder der

Page 31: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

2 Erste Schritte in C# ____________________________________________________31

referenzierten Namespaces stehen anschließend ohne Angabe des Namens zurVerfügung.

using System;Console.WriteLine("Hallo Welt");

Als weitere Alternative kann einem Namespace ein Alias zugewiesen werden. Diesist insbesondere wichtig, wenn zwei Namespaces mit gleichnamigen Element-Namen verwendet werden sollen, der Zugriff aber nicht jeweils durch den mitunterlangen Namespace-Namen, sondern durch einen kurzen Alias erfolgen soll. DieserAlias wird wie folgt hinter dem Schlüsselwort using notiert:

using Alias = Namespace;

Die Ausgabe auf der Konsole könnte demnach zum Beispiel so aussehen:

using sys = System;sys.Console.WriteLine("Hallo Welt");

Die vom .NET Framework angebotenen Funktionalitäten wurden unterhalb desNamespace System zusammengefasst. Die Tabelle 2.2 enthält eine Übersicht derwichtigsten, untergeordneten Namespaces und deren Funktion. Neben diesemNamespace existieren weitere Hersteller-spezifische. Darüber hinaus ist es möglich,eigene Namensräume in Ihren Programmen anzulegen. Hierfür wird das Schema

Herstellername.Produktname.EventuelleUnterelemente

empfohlen. Die Deklaration eines neuen Namespace erfolgt über das Schlüsselwortnamespace und erhält den anschließend notierten Namen. Der Inhalt desNamespaces wird im folgenden durch geschweifte Klammern gekennzeichnetenGültigkeitsbereich vorgenommen.

namespace pal.csharpbuch{// . . .}

Page 32: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

32 _____________________________________________________ 2.8 Namespaces

Tabelle 2.2 Die Namespace-Hierarchie unterhalb von „System“ in der Übersicht

Namespace Beschreibung

System Im Namespace System beginnt die Namespace-Hierarchie des .Net Frameworks. Die zum Frameworkgehörende Funktionalität ist unterhalb angeordnet.Direkt im Namespace enthalten sind die angebotenenDatentypen und andere grundlegende Elemente.

System.CodeDom Klassen zur Erstellung von .NET Programmen zurLaufzeit

System.Collections Verschiedene Grund-Collections zur direktenVerwendung oder Ableitung

System.ComponentModel Funktionalitäten zur Erstellung, Lizenzierung undDistribution von erstellten Komponenten

System.Configugration Konfigurationsdaten einer Applikation

System.Data Zugriff und Management von Daten(banken), zumBeispiel ADO.NET und SQL Server 2000

System.Diagnostics Möglichkeiten zur Diagnose und zum Debugging vonProgrammen

System.DirectoryServices Zugriff auf Active Directory Services (ADSI) wie dieInternet Information Services oder den ExchangeServer 2000

System.Drawing Reichhaltige 2D Grafikbibliotheken und Zugriff aufGDI+

System.Globalization Möglichkeiten zur Globalisierung von internationaleingesetzten Applikationen

System.IO Zugriff auf das Datei-System, inklusive Daten-Operationen auf Datei-Ebene (Storage, etc.)

System.Management Funktionen und Tools zur Zusammenarbeit mit demWeb-Based Enterprise Management (WBEM)

System.Messaging Übermittlung von Nachrichten im Netzwerk undInternet, zum Beispiel Microsoft Message Queue(MSMQ)

System.Net Unterstützung von Netzwerk-Zugriffen und StandardNetzwerk-Protokollen

System.Reflection Zugriff und Manipulation von Meta-Daten einesObjektes

System.Ressources Ressourcen-Verwaltung und -Lokalisierung

System.Security Zugriff auf die Sicherheitsfunktionen des .NETFrameworks

System.ServiceProcess Unterstützung für die Entwicklung von Windows-Diensten (Services)

Page 33: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

2 Erste Schritte in C# ____________________________________________________33

Namespace Beschreibung

System.Text Funktionen zur Bearbeitung von Zeichenketten,strings, reguläre Ausdrücke etc.

System.Threading Zugriff auf Thread-Eigenschaften und Erstellung voneigenen Threads

System.Timers Zeitgesteuerte Ereignisse erstellen

System.Web Unterstützung von Server- und Client-seitiger Internet-Anbindung, enthält auch die Infrastruktur vonASP.NET inklusive WebForms

System.Windows.Forms Windows-Formulare und Dialoge werden auf Basisdieser Funktionen erstellt

2.9 Konsolen-Applikationen

Die Ausgabe von Texten wurde bereits im vorangegangenen Abschnitt kurzgezeigt. Alle Beispiele dieses Buches wurden als Konsolen-Applikationen realisiert.Jegliche Ausgabe von Beispiel-Daten erfolgt also immer im Konsolenfenster. DerVorteil hiervon ist die Schlankheit der Beispiele, die ohne den Ballast vonFormularen daherkommen.Zur Interaktion mit dem Benutzer stehen innerhalb der Klasse Console mehrereMethoden zur Ein- und Ausgabe von Daten im Konsolenfenster zur Verfügung.Die wichtigsten drei Methoden werden in der Tabelle 2.3 aufgelistet undbeschrieben. Alle Methoden sind statisch und werden daher direkt über den Namender Klasse aufgerufen. So erfolgt beispielsweise die Ausgabe eines Textes, wiebereits weiter oben gezeigt, mit Hilfe der folgenden Zeilen:

using System;Console.WriteLine("Hallo Welt");

Tabelle 2.3 Die Methoden der Klasse Console in der Übersicht

Methode Beschreibung

ReadLine Ermöglicht dem Benutzer der Konsolen-Applikation, Daten einzugeben.Die Methode liefert die eingegebenen Daten zurück, sobald derBenutzer diese mit Enter bestätigt. Die Methode kann auch dazuverwendet werden, um die Ausgabe bis zur nächsten Interaktion desBenutzers anzuhalten. Von dieser Möglichkeit wird in den Beispielendes Buches Gebrauch gemacht.

Write Gibt einen übergebenen Text im Konsolenfenster aus, schließt die Zeilejedoch nicht ab

WriteLine Arbeitet wie die Methode Write, schließt die aktuelle Zeile allerdings abund setzt die Position des Cursors an den Beginn der folgenden Zeile

Page 34: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

34 ________________________________________________ 2.10 Die Methode Main

2.10 Die Methode Main

Die Ausführung eines Programms beginnt beim Start des selbigen nicht wahllos aneiner zufälligen Stelle, sondern gezielt in einer bestimmten Methode. Es handeltsich um die statisch deklarierte Methode Main, also die „Hauptmethode“ einesProgramms. Die Methode muss in jedem Programm enthalten sein und zudemeinem bestimmten Aufbau entsprechen. Im einfachsten Fall sieht dieser wie folgtaus:

static void Main(){// Hier startet das Programm}

Die Notation von void gibt an, dass die Methode keinen Rückgabewert hat. Auchwerden keine Parameter an die Methode übergeben. Dies ist wie beschrieben dereinfachste Fall, es gibt also auch noch andere Möglichkeiten.

Übergabe von Kommandozeilen-Parametern

Oft sollen einem Programm über die Kommandozeile Dateinamen, Optionen oderÄhnliches übergeben werden. Auch mit C# ist dies problemlos möglich; dasübergeordnete Framework übernimmt die erforderliche Arbeit. Damit dieInformationen an die Methode weitergereicht werden, muss lediglich einentsprechender Parameter für die Methode Main deklariert werden. Es handelt sichdabei um ein Array vom Datentyp string. Die Deklaration erfolgt auf dienachstehende Weise:

static void Main(string[] args){// Hier startet das Programm}

Der Zugriff auf die einzelnen Elemente des Arrays mit dem hier verwendetenNamen args erfolgt wie in Kapitel 9.1 beschrieben. Jedes Element des Arraysenthält einen Bereich der mit Leerzeichen separierten Kommandozeile desProgrammaufrufes.

Page 35: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

2 Erste Schritte in C# ____________________________________________________35

Rückgabe eines eventuellen Fehlercodes

Bei Windows-Programmen besteht die Möglichkeit, einen Rückgabewert an dasaufrufende Programm zurückzuliefern. Dieses kann unter Umständen eineneventuellen Fehlercode auswerten. Es handelt sich um einen Rückgabewert vomTyp int. Möchten Sie einen solchen Wert zurückliefern, ersetzen Sie in derDeklaration der Methode Main einfach void durch int. Die Rückgabe desgewünschten Wertes erfolgt anschließend über die Sprunganweisung return direktinnerhalb der Methode.

static int Main(){// Hier startet das Programmreturn(0);}

Beachten Sie, dass die Sprunganweisung return das Programm an der aktuellenPosition beendet, es muss sich also um den letzten Befehlsaufruf handeln. DerRückgabewert sollte im Normalfall 0 entsprechen. Nur im Fehlerfall sollte einanderer Wert zurückgeliefert werden.

Parameter und Fehlercode

Sie können die beiden zuvor beschriebenen Möglichkeiten selbstverständlich auchin Kombination verwenden. Die Deklaration der Methode Main sähe in diesem Fallwie folgt aus:

static int Main(string[] args){// Hier startet das Programmreturn(0);}

2.11 Hallo Welt

Ein erstes „Hallo Welt“ darf an dieser Stelle nicht fehlen. Es werden dieInformationen dieses Kapitels in wenigen Zeilen zusammengefasst.

Page 36: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

36 _______________________________________________________ 2.11 Hallo Welt

Im Beispiel wird zunächst der Namespace System referenziert. Alle Elementedieses Namespace stehen fortan direkt zur Verfügung. Innerhalb eines neuenGültigkeitsbereiches der Klasse ConsoleApp wird die statische Methode Main ohneRückgabewert und ohne Parameter deklariert. Diese wird bei der Ausführung desProgramms aufgerufen. Die Methode enthält die Deklaration einer neuen Variablevom Typ string, der bereits in der Zeile der Deklaration dem gewünschten Inhaltzugewiesen wird. Dieser wird anschließend mit Hilfe der Methode WriteLine derKlasse Console im Konsolenfenster ausgegeben. Die Methode ReadLine sorgtdafür, dass die Konsole nicht geschlossen wird, bis die Eingabeaufforderung mitEnter bestätigt wird. Die Abbildung zeigt das Konsolenfenster mit der Ausgabe.

Listing 2.3 hallowelt.cs

using System;

class ConsoleApp{static void Main(){string s = "Hallo Welt";Console.WriteLine(s);Console.ReadLine();}}

Abbildung 2.1 Klappe die erste...

Page 37: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

3Klassen &

objektorientierteProgrammierung – Teil I

Was ist ein Objekt?

Was ist eine Klasse?

Instanziierung einer Klasse

Terminierung eines Objekts

Deklaration einer neuen Klasse

Page 38: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

38 ____________________________________________________________________

Inhaltsübersicht Kapitel 3

3 Klassen & objektorientierte Programmierung – Teil I ..................................39

3.1 Was ist ein Objekt?..............................................................................................393.2 Was ist eine Klasse? ............................................................................................403.3 Instanziierung einer Klasse..................................................................................413.4 Terminierung eines Objekts.................................................................................423.5 Deklaration einer neuen Klasse ...........................................................................433.5.1 Dynamisch versus statisch ...................................................................................463.5.2 Eigenschaften deklarieren....................................................................................483.5.3 Methoden deklarieren ..........................................................................................533.5.4 Ereignisse deklarieren..........................................................................................563.5.5 Das Schlüsselwort this.........................................................................................623.5.6 Modifikatoren ......................................................................................................633.5.7 Konstruktor..........................................................................................................673.5.8 Destruktor............................................................................................................723.5.9 Attribute...............................................................................................................74

Page 39: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

____________________________________________________________________ 39

3 Klassen & objektorientierteProgrammierung – Teil I

„Das ganze Leben ist ein Objekt.“ Dieser Spruch trifft zwar auf das reale Lebennicht unbedingt zu, für C# jedoch schon. Als vollständig objektorientierteProgrammiersprache sieht C# in jeder Variablen und jedem Element ein Objekt.

3.1 Was ist ein Objekt?

Ein Objekt ist eine logische Informationseinheit. Ein Objekt fasst eine oder auchmehrere Informationen zusammen und stellt Möglichkeiten zur Bearbeitung dieserInformationen zur Verfügung. Nehmen Sie zum Beispiel Ihre Katze, die Ihnenvielleicht auf dem Schoß sitzt, während Sie dieses Buch studieren. Auf dieProgrammierung umgesetzt, wäre Ihre Katze ein Objekt. Mal angenommen, IhreKatze wäre wirklich nur ein Objekt und nicht das liebe, warme und schnurrendeGeschöpf, das sie ist, dann gelten folgende Beobachtungen:• Das Objekt hat feste Eigenschaften wie die Augenfarbe.• Das Objekt hat dynamische, also sich ändernde Eigenschaften wie zum Beispiel

den Zufriedenheitsstatus.• Das Objekt hat Methoden, die von außen gesteuert werden. Hierzu gehört bei

Hauskatzen beispielsweise die Versorgung mit Nahrung.• In vielen Fällen kann das Objekt auch Ereignisse auslösen. Bei einer Katze ist

das ganz sicher der Fall, denn wenn sie laut miaut oder ein Häufchen gemachthat, dann ist das durchaus ein Ereignis, das gewisse Reaktionen zur Folge hat.

In C# werden alle Informationen als Objekte dargestellt. Alle diese Objekte werdenvon der Mutter aller Objekte, dem Datentyp mit dem treffenden Namen object,abgeleitet. Dieses Basisobjekt liefert bereits eine Reihe von Methoden. Diese sindin allen Unterobjekten vorhanden. Bei dem der Katze übergeordneten Objekt, demTier, wäre eine solche grundsätzlich vorhandene Methode die Versorgung mitNahrung, denn jedes Tier braucht schließlich etwas zu futtern. Weitere individuelleEigenschaften, Methoden und eventuell auch Ereignisse werden spezifisch vomObjekt angeboten.

object

Page 40: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

40 _______________________________________________ 3.2 Was ist eine Klasse?

Abbildung 3.1 Hilfe, meine Katze ist ein Objekt!

3.2 Was ist eine Klasse?

Die objektorientierte Programmierung wird häufig auch als Klassenprogram-mierung bezeichnet. Eine Klasse ist quasi das Grundgerüst eines Objektes, also derPlan, nach dem dieses Objekt definiert ist. Auf das Beispiel der Katze angewandt,würde die Klasse alle verfügbaren Eigenschaften, Methoden und Ereignisse einerKatze definieren und die dahinterliegende Funktion implementieren. So würdebeispielsweise die Methode zur Versorgung mit Nahrung diese aufnehmen, verar-beiten und zu guter Letzt das Ereignis Häufchen triggern.Die Klasse ist also die Definition eines Objektes, während dieses eine Instanz, alsodie Anwendung der Klasse ist.

Page 41: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

3 Klassen & objektorientierte Programmierung – Teil I __________________________41

Abbildung 3.2 Eine Katze – ganz „Objektiv“ betrachtet

3.3 Instanziierung einer Klasse

Die Instanziierung einer Klasse erfolgt wie bei Variablen , die zu Beginn desKapitels vorgestellt wurden. Das ist auch ganz logisch, denn schließlich handelt essich auch hierbei um Objekte von einem bestimmten Typ. Konkret sieht das wiefolgt aus:

Katze meineKatze = new Katze(); Klasseinstanziieren

Page 42: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

42 __________________________________________ 3.4 Terminierung eines Objekts

Zunächst wird der Datentyp, also der Name der Klasse, notiert. Anschließend folgtder Name der gewünschten Variablen und danach deren Zuweisung. In diesem Fallwird über das Schlüsselwort new eine neue Instanz der Klasse Katze instanziiert. Eswird also quasi eine neue Katze geboren, in diesem Fall ohne Mutter und Vater –langsam schweifen wir also in die virtuelle Realität ab.

Durch die Instanziierung weiß C#, dass Sie nun auf das Objekt zugreifen möchten,und kümmert sich automatisch um die Reservierung des dafür notwendigenSpeichers. Sie müssen diesen also nicht wie bei anderen Sprachen oder Systemenzuvor explizit anfordern.Die Variable meineKatze enthält nicht die Katze selbst, sondern lediglich einenVerweis auf dieses Objekt. Auf diese Weise ist es auch möglich, dass mehrereVariable auf ein und das selbe Objekt verweisen. Das folgende Beispiel machtdieses Prinzip deutlich.

Katze meineKatze = new Katze();Katze KatzeMeinerFrau = meineKatze;

Ihre Katze ist auch die Katze Ihrer Frau und somit halten Sie beide einen Verweisauf ein und dieselbe Katze, also dasselbe Objekt.

3.4 Terminierung eines Objekts

Nachdem Sie die Klasse instanziiert haben, befindet sich ein entsprechendes Objektim Speicher. Wird der Geltungsbereich der Variablen verlassen und besteht keinanderer Verweis auf das Objekt, wird dieses nicht länger benötigt.Die Entfernung des Objektes aus dem Speicher, also die Terminierung, übernimmtim .NET Framework und somit auch in C# die so genannte Garbage Collection. Eshandelt sich quasi um die Müllabfuhr, die unbenötigten Speicher einsammelt undder Wiederverwertung zuführt. Wie es bei der Müllabfuhr halt so ist, steht diesenicht vor dem Haus und wartet den ganzen Tag darauf, dass Sie etwas Speicherloswerden wollen. Vielmehr kommt die Müllabfuhr bei Ihnen vorbei, wenn siegerade etwas (CPU-) Zeit hat.Eine explizite Freigabe des Speichers ist also nicht notwendig. Falls erwünscht,können Sie eine Objektinstanz aber explizit terminieren. Hierzu setzen Sie dieverweisende Variable einfach ins Nirwana, also gleich null. Beachten Sie, dass diesnur bei Verweistypen, nicht aber bei Wertetypen wie short, int, long, etc. möglichist. Zudem löscht die Zuweisung lediglich diesen einen Verweis. Sofern alsoweitere Verweise auf das Objekt existieren, bleibt dieses weiter bestehen.

Speicherreservieren

Verweis kopieren

GarbageCollection

Page 43: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

3 Klassen & objektorientierte Programmierung – Teil I __________________________43

Angewandt auf unser kleines Beispielobjekt, wirkt die Terminierung auf den erstenBlick ein wenig brutal:

meineKatze = null;

Auf den zweiten Blick ist es aber gar nicht sooo schlimm, denn Ihre Frau hält janoch einen Verweis auf das Objekt und somit wurde Ihre Katze nicht wirklichterminiert.

3.5 Deklaration einer neuen Klasse

Um alle Ihre Haustiere abzubilden, können Sie selbstverständlich auch eigeneKlasse deklarieren. Neben dem grundsätzlichen Aufbau wird dabei auch die interneProgrammierung vorgenommen. Erst diese Kombination aus Deklaration undImplementation ergibt letztlich die Klasse.Jede Klasse und somit jedes Objekt ist beziehungsweise sollte so angelegt sein, dasses eine bestimmte logische Informationseinheit (und nur diese) mit allen Aspektenrepräsentiert. Während dies bei der Katze ganz klar vorgegeben ist, liegt genau indiesem Punkt die Schwierigkeit der objektorientierten Programmierung. EinEntwickler muss planen und differenzieren, was seine Informationseinheit ist undwie sich diese von anderen abgrenzt. Je allgemeiner die Definition erfolgt, destobesser lassen sich Klassen später wieder verwenden.Die Deklaration einer Klasse erfolgt mit dem Schlüsselwort class gefolgt von demgewünschten Namen der Klasse. Alles Weitere wird anschließend demGültigkeitsbereich der Klasse zugeordnet und daher eingerückt in geschweiftenKlammern notiert.

Listing 3.1 class1.cs

class Katze{// Implementation der Klasse Katze

}

Innerhalb des Gültigkeitsbereiches können Sie nun Variablen, Eigenschaften,Methoden und so weiter definieren. Variablen, so genannte Mitglieder-Variablender Klasse, werden dabei einfach wie gewohnt notiert. Solche Variablen sind dannausschließlich innerhalb der Klasse verfügbar und können nicht von außenangesprochen werden.

Objektterminieren

Schlüsselwortclass

Page 44: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

44 _______________________________________ 3.5 Deklaration einer neuen Klasse

Listing 3.2 class2.cs

class Katze{

string Name;

}

...

Katze meineKatze = new Katze();meineKatze.Name = "Filou";

Dieser Aufruf führt zu einem Fehler, da die Variable nur lokal innerhalb der Klasseverfügbar ist. Die Abbildung zeigt die Ausgabe der Fehlermeldung durch denCompiler.

Abbildung 3.3 Auf die Variable kann nur innerhalb der Klasse zugegriffen werden.

Sofern eine Variable auch von außen angesprochen werden soll, muss diese miteinem so genannten Modifikator versehen werden. Oft verwendet wird derModifikator public (übersetzt: „öffentlich“), der bewirkt, dass die Variablebeliebig von außen gelesen und gesetzt werden kann.Das folgende Beispiel verwendet den beschriebenen Modifikator und erlaubt so denZugriff auf die Variable Name.

Modifikator public

Page 45: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

3 Klassen & objektorientierte Programmierung – Teil I __________________________45

Listing 3.3 class3.cs

using System;

class Katze{public string Name;}

class ConsoleApp{static void Main(){Katze meineKatze = new Katze();

// Ich gebe der Katze einen NamenmeineKatze.Name = "Filou";Console.WriteLine("Meine Katze heißt: ");Console.WriteLine(meineKatze.Name + "");

// Ich gebe der Katze einen neuen NamenmeineKatze.Name = "Hansi";

// Doch wie heißt die Katze nun?Console.WriteLine("Meine Katze heißt: ");Console.WriteLine(meineKatze.Name + "");

Console.ReadLine();}}

Die Abbildung zeigt die geänderte Ausgabe im Konsolenfenster. Der Zugriff derVariablen ist ganz beliebig möglich und so können Sie der Katze statt des schönenNamens Filou einen anderen verpassen. Ob Hansi allerdings wie ein Wellensittichpiepsen wird, ist ungewiss.

Page 46: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

46 _______________________________________ 3.5 Deklaration einer neuen Klasse

Abbildung 3.4 Die öffentliche Variable kann sowohl gesetzt als auch gelesen werden.

Es stehen eine Reihe weiterer Modifikatoren zur Verfügung. Diese werden weiterunten unter der gleichnamigen Überschrift vorgestellt.

3.5.1 Dynamisch versus statisch

Ein Objekt ist immer die Instanziierung einer Klasse. Ruft man eine Eigenschaftdes Objektes, also der Instanz einer Klasse auf, so kann diese einen vollkommenanderen Wert enthalten als eine andere Instanz derselben Klasse. Die Eigenschaftenund Methoden eines Objektes sind also dynamische Mitglieder.Das folgende Beispiel zeigt zwei Instanzen einer Klasse, deren Eigenschaft Nameeinen jeweils anderen Namen enthält.

Listing 3.4 class4.cs

class Katze{public string Name;}

class ConsoleApp{static void Main(){Katze meineKatze1 = new Katze();meineKatze1.Name = "Filou";

Katze meineKatze2 = new Katze();meineKatze2.Name = "Shari";

Page 47: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

3 Klassen & objektorientierte Programmierung – Teil I __________________________47

Console.WriteLine("Meine erste Katze heißt: " +meineKatze1.Name);

Console.Write ("Meine zweite Katze heißt: " +meineKatze2.Name);

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Meine erste Katze heißt: FilouMeine zweite Katze heißt: Shari

Neben dynamischen existieren auch statische Mitglieder einer Klasse. DieseMitglieder stehen global und ohne Instanz einer Klasse zur Verfügung. Sie werdenauch nicht auf Basis der Instanz, sondern auf Basis des Klassennamensangesprochen. Aus diesem Grund kann eine statische Eigenschaft immer nur ganzgenau einen Wert enthalten. Die Implementierung der statischen Mitglieder erfolgtinnerhalb der Klasse analog zu den dynamischen. Allerdings muss eine besondereKennzeichnung durch den Modifikator static erfolgen. Es ergibt sich folgendesSchema:

public static Mitgliedsname(){// Befehlszeilen}

Der Aufruf sieht so aus:

Klassenname.Mitgliedsname()

Statische Mitglieder bieten sich immer dann an, wenn eine Funktionalitätunabhängig von einer bestimmten Instanz, aber dennoch im logischen Verbund mitder Klasse verwendet werden soll.Das nachfolgende Beispiel implementiert auf Basis der Klasse Katze eine statischeMethode zur Ermittlung eines zufälligen Namens für die Katze. Dieser wird auseinem Fundus an hinterlegten Namen zufällig ausgewählt.

static

Page 48: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

48 _______________________________________ 3.5 Deklaration einer neuen Klasse

Listing 3.5 class5.cs

using System;

class Katze{

public string Name;

public static string GetRandomName(){string[] Names = {"Pussi", "Muschi", "Mausi", "Mieze"};Random rnd = new Random();int rndValue = rnd.Next(0, Names.GetUpperBound(0));return(Names[rndValue]);}

}

class ConsoleApp{static void Main(){Katze meineKatze = new Katze();meineKatze.Name = Katze.GetRandomName();

Console.WriteLine("Meine Katze heißt: " +meineKatze.Name);

Console.ReadLine();}}

Die Ausgabe im Konsolenfenster sieht ganz unterschiedlich aus, denn schließlichwird der Name der Katze zufällig ausgewählt:

Meine Katze heißt: Pussi

3.5.2 Eigenschaften deklarieren

Der öffentliche Zugriff auf eine Variable ist zwar prinzipiell gut, allerdings nichtkontrollierbar, da dieser Zugriff direkt erfolgt und Sie somit keinerleiEinflussmöglichkeiten haben. Öffentliche Variablen werden daher selten verwendetund stattdessen in Form von Eigenschaften implementiert.

Page 49: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

3 Klassen & objektorientierte Programmierung – Teil I __________________________49

Eigenschaften werden ähnlich deklariert, bieten aber eine kontrollierteZugriffsfunktionalität und enthalten anders als Variablen direkt keine Daten. DieFunktionen zum Abfragen und Setzen der Eigenschaft werden über dieSchlüsselwörter get und set implementiert. Diese verfügen jeweils über eineneigenen (eingeklammerten) Geltungsbereich und kommunizieren mit derAußenwelt über die Schlüsselwörter return zur Rückgabe einer abgefragtenEigenschaft und value zur Ermittlung des zu setzenden Wertes. Es ergibt sichfolgendes Grundschema für die Deklaration einer Eigenschaft.

Modifikator Datentyp Eigenschaftsname{get{return(Mitgliedsvariable);}set{Mitgliedsvariable = value;}}

Im folgenden Beispiel wurde die Benennung der Katze aufgenommen. Der Nameder Katze wird nun als Eigenschaft implementiert. Sowohl get als auch set sindvorhanden. Da die Eigenschaft selbst keine Daten speichern kann, wird zusätzlichdie lokale Variable _Name benötigt. Der Name kann allerdings beliebig gewählt, daeine Zuordnung explizit durch entsprechende Zuweisung unterhalb von getbeziehungsweise set vorgenommen werden muss. Das Problem der unschönenUmbenennung wurde hier übrigens gelöst. Durch eine einfach Abfrage istsichergestellt, dass nur einmal ein Name für die Katze vergeben werden kann.Dieser kann anschließend nicht mehr geändert werden, schließlich hat sich dieKatze an den Namen gewöhnt.

Listing 3.6 class6.cs

using System;

class Katze{

string _Name;

public string Name{get{

get und set

Page 50: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

50 _______________________________________ 3.5 Deklaration einer neuen Klasse

return(_Name);}set{if(_Name==null)_Name = value;

}}

}

class ConsoleApp{static void Main(){Katze meineKatze = new Katze();

// Ich gebe der Katze einen NamenmeineKatze.Name = "Filou";Console.WriteLine("Meine Katze heißt: ");Console.WriteLine(meineKatze.Name + "");

// Ich gebe der Katze einen neuen NamenmeineKatze.Name = "Hansi";

// Doch wie heißt die Katze nun?Console.WriteLine("Meine Katze heißt: ");Console.WriteLine(meineKatze.Name + "");

Console.ReadLine();}}

Der Zugriff erfolgt komplett analog zum vorherigen Beispiel. Eine besondereBehandlung bei Eigenschaften im Vergleich zu öffentlichen Variablen ist also nichtnotwendig. Die Abbildung zeigt das geänderte Ergebnis.

Page 51: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

3 Klassen & objektorientierte Programmierung – Teil I __________________________51

Abbildung 3.5 Filou bleibt Filou.

Das folgende Beispiel zeigt zwei weitere Eigenschaften: Alter undMenschenalter. Diese greifen die gebräuchliche Rechnung auf, dass eintatsächliches Katzenalter in etwa sieben Menschenjahren entspricht. Zunächst wirddas Alter über die gleichnamige Eigenschaft gesetzt und in der lokalen Variable_Alter abgelegt. Die Eigenschaft MenschenAlter greift ebenfalls auf die Variablezu, gibt diese jedoch multipliziert mit 7 zurück.

Listing 3.7 class7.cs

using System;

class Katze{

string _Name;int _Alter;

public string Name{get{return(_Name);}set{if(_Name==null)_Name = value;

}}

public int Alter

Page 52: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

52 _______________________________________ 3.5 Deklaration einer neuen Klasse

{get{return(_Alter);}set{_Alter = value;}}

public int MenschenAlter{get{return(_Alter*7);}}

}

class ConsoleApp{static void Main(){Katze meineKatze = new Katze();meineKatze.Name = "Filou";meineKatze.Alter = 12;

Console.WriteLine("Meine Katze heißt ");Console.WriteLine(meineKatze.Name);Console.WriteLine(" und ist umgerechnet ");Console.WriteLine(meineKatze.MenschenAlter.ToString());Console.WriteLine(" Menschenjahre alt.");

Console.ReadLine();}}

Die Ausgabe im Konsolenfenster zeigt, dass die Umrechnung von tatsächlichemAlter in ein angenommenes Menschenalter innerhalb der Eigenschaft funktioniert.

Meine Katze heißt Filou und ist umgerechnet 84 Menschenjahre alt.

Sie haben vielleicht gesehen, dass die Definition des Schlüsselwortes set für dieEigenschaft MenschenAlter fehlt. Das ist keine Unachtsamkeit, sondern volleAbsicht gewesen. Lässt man eines der beiden Schlüsselworte get oder set einfach

Schreib-geschützeEigenschaften

Page 53: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

3 Klassen & objektorientierte Programmierung – Teil I __________________________53

weg, so ergibt sich ein geändertes Verhalten der Eigenschaft. Diese kann dann nurgesetzt (write-only) oder wie in diesem Fall nur abgefragt (read-only) werden.

3.5.3 Methoden deklarieren

Methoden werden ähnlich wie Eigenschaften deklariert. Nach demZugriffsmodifikator folgt der Datentyp sowie der Name der Methode. In rundenKlammern folgen nun die Parameter der Methode. Diese werden wiederum mit demDatentyp sowie dem gewünschten Namen des Parameters notiert. Die Parameterstehen anschließend in Form von lokalen Variablen zur Verfügung. DieFunktionalität der Methode wird in einem eigenen Geltungsbereich hinterlegt, derin geschweifte Klammern eingerahmt ist. Der Rückgabewert der Methode wird wiebei Eigenschaften mit dem Schlüsselwort return angegeben. Das Schlüsselwortkann beliebig häufig beispielsweise innerhalb von Bedingungen oder switch-Konstrukten innerhalb der Methode verwendet werden und führt zur sofortigenRückkehr zur aufrufenden Programmzeile. Es ergibt sich das folgende Schema.

Modifikator Datentyp Methodenname(Datentyp Parameter){Befehlszeilen;// weitere Abarbeitung der Methodereturn(Rückgabewert);}

Auch auf unsere Beispiel-Klasse einer Katze lassen sich Methoden anwenden. Imfolgenden Beispiel wird die Methode Fuettern implementiert. Diese erwartet alsParameter die Nahrung sowie die Anzahl der Portionen. Gehört die Nahrung zueiner bestimmten Gruppe, erhöht sich der Zufriedenheitsindex der Katze um dieAnzahl der Portionen. Bei jeder anderen Nahung verringert sich der Indexentsprechend.

Listing 3.8 class8.cs

using System;

class Katze{

int _Zufriedenheitsindex;

public int Zufriedenheitsindex{get{

return

Page 54: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

54 _______________________________________ 3.5 Deklaration einer neuen Klasse

return(_Zufriedenheitsindex);}set{_Zufriedenheitsindex = value;}}

public bool Fuettern(string Nahrung, int Portionen){

switch(Nahrung.ToLower()){case "thunfisch":case "rinderhack":case "hühnchen":this.Zufriedenheitsindex+=Portionen;return(true);

default:this.Zufriedenheitsindex-=Portionen;return(false);

}

}

}

class ConsoleApp{static void Main(){Katze meineKatze = new Katze();meineKatze.Zufriedenheitsindex = 5;

Console.WriteLine("Zufriedenheitsindex vor Fütterung: ");Console.WriteLine(meineKatze.Zufriedenheitsindex.ToString() + "");

if(meineKatze.Fuettern("thunfisch", 3))Console.WriteLine("Das hat geschmeckt!");elseConsole.WriteLine("Das war keine gute Idee!");

Console.WriteLine("Zufriedenheitsindex nach Fütterung: ");Console.WriteLine(meineKatze.Zufriedenheitsindex.ToString() + "");

Console.ReadLine();}}

Page 55: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

3 Klassen & objektorientierte Programmierung – Teil I __________________________55

Die Methode liefert einen logischen (booleschen) Wert zurück, ob die Nahrunggenehm war oder nicht. Dieser wird über eine if-Bedingung abgefragt und einentsprechender Text im Konsolenfenster ausgegeben. Die vollständige Ausgabe desBeispiels sieht so aus:

Zufriedenheitsindex vor Fütterung: 5Das hat geschmeckt!Zufriedenheitsindex nach Fütterung: 8

Glück gehabt, die Katze mag den Tunfisch scheinbar. Der Zufriedenheitsindex hatsich um die Anzahl der Nahrungsportionen erhöht.Nicht immer sind Sie am Rückgabewert eine Methode interessiert und manchmalgibt es gar keine Information, die zurückgegeben werden könnte. In diesem Fallgeben Sie als Datentyp void an. Der Aufruf von return ist in diesem Fallüberflüssig beziehungsweise nicht möglich. Am Beispiel der Karte könnte dieMethode Streicheln ohne Rückgabewert auskommen.

Listing 3.9 class9.cs

using System;

class Katze{

int _Zufriedenheitsindex;

public int Zufriedenheitsindex{get{return(_Zufriedenheitsindex);}set{_Zufriedenheitsindex = value;}}

public void Streicheln(){this.Zufriedenheitsindex+=10;}

}

class ConsoleApp{

Schlüsselwortvoid

Page 56: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

56 _______________________________________ 3.5 Deklaration einer neuen Klasse

static void Main(){Katze meineKatze = new Katze();meineKatze.Zufriedenheitsindex = 5;

Console.WriteLine("Zufriedenheitsindex vor dem Streicheln: ");Console.WriteLine(meineKatze.Zufriedenheitsindex.ToString() + "");

meineKatze.Streicheln();

Console.WriteLine("Zufriedenheitsindex nach dem Streicheln: ");Console.WriteLine(meineKatze.Zufriedenheitsindex.ToString() + "");

Console.ReadLine();}}

Die Ausgabe zeigt, dass auch dies der Katze gefallen hat:

Zufriedenheitsindex vor dem Streicheln: 5Zufriedenheitsindex nach dem Streicheln: 15

3.5.4 Ereignisse deklarieren

Nach den Eigenschaften und Methoden sind Ereignisse ein drittesCharaktermerkmal von Klassen. Allerdings bietet nur ein Bruchteil der verfügbarenKlassen Ereignisse an, denn diese werden nur dann benötigt, wenn auf bestimmteÄnderungen eines Objektes reagiert werden soll.Eigenschaften und Methoden wurden nach einem einheitlichen und sehr einfachenSchema deklariert. Auch für Ereignisse gibt es ein solches Schema, dieses ist aberein Stück weit komplexer. Das Ereignis besteht aus mehreren Einheiten: derDeklaration (delegate), der Instanziierung (event), dem Aufruf und schließlich derBehandlung.Die Deklaration eines Ereignisses erfolgt über das Schlüsselwort delegate. Wiebei einer Methode wird zunächst der Modifikator notiert, es folgt der Datentyp desRückgabewertes (beziehungsweise void, wenn es keinen geben soll), der Name derDeklaration und anschließend die Parameter in runden Klammern.

Modifikator delegate Datentyp DelegateName(Datentyp Parameter);

Nachdem eine Ereignis-Deklaration allgemein verwendet werden kann, definiertsich über das Schlüsselwort event ein spezifisches Ereignis. Ähnlich wie bei einerKlasse handelt sich bei einem event also um die Instanziierung der Deklaration

delegate

event

Page 57: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

3 Klassen & objektorientierte Programmierung – Teil I __________________________57

(delegate). Da der Aufbau bereits feststeht, werden lediglich der Name derDeklaration sowie der Name dieses speziellen Ereignisses angegeben.

Modifikator event DelegateName EreignisName

Damit ein Ereignis nicht nur eintritt, sondern auch bemerkt wird, benötigt man eineEreignisbehandlung. Es handelt sich dabei um eine Methode, die dem Aufbau derEreignisdeklaration (delegate) entspricht. Typischerweise wird diese Methode inder aufrufenden Klasse implementiert. Hier wird angegeben, was bei dieserspeziellen Instanz einer Klasse im Falle eines eintretenden Ereignisses geschehensoll.

MethodenName(Datentyp Parameter){Ereignisbehandlung}

Damit klar ist, welche Ereignisbehandlung verwendet werden soll, muss diese beider Instanz der Klasse angemeldet werden. Hierzu wird das folgende Schemaverwendet.

KlassenInstanz.EreignisName += new DelegateName(MethodenName);

Auch ein Abmelden der Ereignisbehandlung sollte unbedingt vorgenommenwerden, wenn diese nicht weiter benötigt wird. Der Aufruf erfolgt analog.

KlassenInstanz.EreignisName -= new DelegateName(MethodenName);

Sehr wichtig in beiden Fällen ist die Verwendung von += beziehungsweise -=, dennes können auch mehrere Ereignisbehandlungen für ein und dasselbe Ereignisangemeldet werden. Diese Zeichen sind Zuweisungsoperatoren. Der Wert rechtswird zu dem Wert links addiert beziehungsweise von diesem subtrahiert undanschließend der links notierten Variable zugewiesen. Eine Übersicht dieser undweiterer Operatoren finden Sie übrigens im gleichnamigen Kapitel weiter unten.Zu guter Letzt benötigen wir noch einen Auslöser für das Ereignis. Dieser befindetsich in der Regel innerhalb der Klasse und wird innerhalb einer Methode oderEigenschaft ausgeführt. Unbedingt erforderlich ist dabei immer eine Abfrage, obzumindest eine Ereignisbehandlung angemeldet wurde. Dies geschieht durch denVergleich der Ereignisinstanz mit null. Es ergibt sich das folgende Schema.

if(EreignisName != null)EreignisName(Parameter);

Eventhandler

Eventhandleranmelden

Page 58: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

58 _______________________________________ 3.5 Deklaration einer neuen Klasse

Wie Sie sehen, sind Ereignisse auf den ersten Blick nicht ganz einfach. Hat mansich jedoch einmal auf das System eingestellt, wird man die daraus resultierendenVorteile schnell schätzen lernen. Im Folgenden ein kleines Beispiel, das dasBeschriebene verdeutlichen soll. Die Klasse Test enthält eine Ereignisdeklarationund eine Ereignisinstanz. Die Methode EreignisInitiieren löst das Ereignis aus.Außerhalb der Klasse ist eine Behandlung implementiert, die die übergebeneZeichenkette im Konsolenfenster ausgibt.

Listing 3.10 class10.cs

using System;

class Test{

public delegate void EreignisDeklaration(string Parameter);public event EreignisDeklaration EreignisInstanz;

public void EreignisInitiieren(){if(EreignisInstanz != null)EreignisInstanz("Das Ereignis ist eingetreten!");

}

}

class ConsoleApp{

static void EreignisBehandlung(string p){Console.WriteLine(p);}

static void Main(){Test TestKlasse = new Test();

TestKlasse.EreignisInstanz += newTest.EreignisDeklaration(EreignisBehandlung);

TestKlasse.EreignisInitiieren();

Page 59: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

3 Klassen & objektorientierte Programmierung – Teil I __________________________59

TestKlasse.EreignisInstanz -= newTest.EreignisDeklaration(EreignisBehandlung);

Console.ReadLine();}

}

Eigentlich ist es doch ganz einfach, ein Ereignis zu erstellen. Die Ausgabe imKonsolenfenster zeigt, dass es funktioniert:

Das Ereignis ist eingetreten!

Werden mehrere Ereignisbehandlungen angemeldet, so werden diese der Reiheihrer Anmeldung nach abgearbeitet. Im nun folgenden Beispiel wird der Texteinfach doppelt ausgegeben, da zwei Behandlungen implementiert und angemeldetwurden.

Listing 3.11 class11.cs

using System;

class Test{

public delegate void EreignisDeklaration(string Parameter);public event EreignisDeklaration EreignisInstanz;

public void EreignisInitiieren(){if(EreignisInstanz != null)EreignisInstanz("Das Ereignis ist eingetreten!");

}

}

class ConsoleApp{

static void EreignisBehandlung(string p){Console.WriteLine(p + "");}

static void EreignisBehandlung2(string p){Console.WriteLine(p + " --> Nummer 2");}

Page 60: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

60 _______________________________________ 3.5 Deklaration einer neuen Klasse

static void Main(){Test TestKlasse = new Test();

TestKlasse.EreignisInstanz += newTest.EreignisDeklaration(EreignisBehandlung);TestKlasse.EreignisInstanz += newTest.EreignisDeklaration(EreignisBehandlung2);

TestKlasse.EreignisInitiieren();

TestKlasse.EreignisInstanz -= newTest.EreignisDeklaration(EreignisBehandlung2);TestKlasse.EreignisInstanz -= newTest.EreignisDeklaration(EreignisBehandlung);

Console.ReadLine();}}

Auch hier zeigt die Ausgabe im Konsolenfenster, dass beide Ereignisbehandlungenabgearbeitet wurden:

Das Ereignis ist eingetreten!Das Ereignis ist eingetreten! --> Nummer 2

Natürlich soll auch das Katzenbeispiel ein Ereignis erhalten, schließlich haben Siesich doch schon an meine Katze Filou gewöhnt, oder? Das Ereignis soll eintreten,wenn die Katze höchst zufrieden ist. Hierzu wurde eine entsprechende delegatesowie ein event erstellt. Das Ereignis wird ausgelöst, sobald die EigenschaftZufriedenheitsindex neu gesetzt wird und über dem Wert 10 liegt. Einindirekter Auslöser hierfür ist im Beispiel die Methode Streicheln, die den Indexum 10 erhöht. Der aktuelle Index wird über das Ereignis an die Behandlung weiter-gegeben und von dort im Konsolenfenster ausgegeben.

Listing 3.12 class12.cs

using System;

class Katze{

public delegate void SuperZufriedenDelegate(int AktuellerIndex);public event SuperZufriedenDelegate SuperZufrieden;

int _Zufriedenheitsindex;

Page 61: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

3 Klassen & objektorientierte Programmierung – Teil I __________________________61

public int Zufriedenheitsindex{get{return(_Zufriedenheitsindex);}set{_Zufriedenheitsindex = value;if(_Zufriedenheitsindex>10){if(SuperZufrieden != null)SuperZufrieden(_Zufriedenheitsindex);

}}}

public void Streicheln(){this.Zufriedenheitsindex+=10;}

}

class ConsoleApp{

// Hier wird das Ereignis verarbeitetstatic void SuperZufriedenEvent(int Index){Console.WriteLine("Die Katze ist SUPER ZUFRIEDEN (" +Index + ")!");

}

static void Main(){

Katze meineKatze = new Katze();meineKatze.Zufriedenheitsindex = 5;

meineKatze.SuperZufrieden += newKatze.SuperZufriedenDelegate(SuperZufriedenEvent);

Console.WriteLine("Zufriedenheitsindex vor dem Streicheln: ");Console.WriteLine(meineKatze.Zufriedenheitsindex.ToString() + "");

meineKatze.Streicheln();

Page 62: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

62 _______________________________________ 3.5 Deklaration einer neuen Klasse

Console.WriteLine("Zufriedenheitsindex nach dem Streicheln: ");Console.WriteLine(meineKatze.Zufriedenheitsindex.ToString() + "");

meineKatze.SuperZufrieden -= newKatze.SuperZufriedenDelegate(SuperZufriedenEvent);

Console.ReadLine();}}

Die Ausgabe im Konsolenfenster zeigt, dass das Ereignis direkt beim Hochsetzendes ZufriedenheitsIndex durch die Methode Streicheln ausgelöst und einentsprechender Text ausgegeben wird.

Zufriedenheitsindex vor dem Streicheln: 5Die Katze ist SUPER ZUFRIEDEN (15)!Zufriedenheitsindex nach dem Streicheln: 15

3.5.5 Das Schlüsselwort this

Oft existieren innerhalb einer Klasse konkurrierende Namen, insbesonderezwischen Mitgliedern der Klasse und Parametern. Die lokal deklarierten Parameterhaben dabei Vorrang vor den weiter oben deklarierten Mitgliedern der Klasse. Dochwie sollen diese angesprochen werden? Das Schlüsselwort this liefert einenVerweis auf die aktuelle Instanz der eigenen Klasse. So lassen sich nicht nur dieMitglieder der Klasse direkt ansprechen, es kann auch ein Verweis auf die Instanzan eine andere Klasse weitergegeben werden.Das Beispiel zeigt zwei konkurrierende Variablen. Es existiert einmal eineEigenschaft Name und innerhalb der Methode SetName ein Parameter mit dergleichen Namensgebung. Innerhalb der Methode wird das Schlüsselwort thisverwendet, um der Eigenschaft den Inhalt des Parameters zuzuweisen.

Listing 3.13 this1.apsx

using System;

class Test{

string _Name;

public string Name{

this

Page 63: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

3 Klassen & objektorientierte Programmierung – Teil I __________________________63

get{return(_Name);}set{_Name = value;}}

public void SetName(string Name){this.Name = Name;}

}

class ConsoleApp{static void Main(){Test t = new Test();

t.SetName("Irgendein Name ;-)");

Console.WriteLine("Name: " + t.Name);

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Name: Irgendein Name ;-)

Das Schlüsselwort this kann in Instanz-Mitglieder und Konstruktoren aufgerufenwerden. Eine Verwendung innerhalb von statischen Mitgliedern ist hingegen nichtmöglich. Eigentlich nur logisch, denn auf welche Instanz sollte das Schlüsselwortsich beziehen, wenn ein statisches Mitglied doch direkt aus der Klasse und nicht auseiner Instanz dieser aufgerufen wird.

3.5.6 Modifikatoren

Das Stichwort Modifikatoren ist in den vorangegangenen Abschnitten bereits desöfteren gefallen. Aber was sind Modifikatoren eigentlich? Es handelt sich umSchlüsselwörter, die die nachfolgende Deklaration modifizieren. Angewendet

Page 64: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

64 _______________________________________ 3.5 Deklaration einer neuen Klasse

werden können Modifikatoren zum Beispiel auf Variablen, Klassen, EigenschaftenMethoden und Ereignisse. Oft lassen sich auch mehrere Modifikatoren inKombination anwenden, zum Beispiel public und readonly. Die Tabelle zeigt diein C# zur Verfügung stehenden Modifikatoren. Zugriffsmodifikatoren sind miteinem * gekennzeichnet.

Tabelle 3.1 Modifikatoren in der Übersicht

Modifikator Beschreibung

abstract Der Modifikator kann auf Klassen, Eigenschaften und Methoden angewandtwerden. Er kennzeichnet das jeweilige Element als abstrakt. Dies bedeutet,dass dieses nicht implementiert ist und dies in einer abgeleiteten Klasseexplizit überschrieben werden muss (vergleiche „Klassen & objektorientierteProgrammierung – Teil II“).

const Dieser Modifikator kann auf eine Variable oder ein Feld angewandt werdenund kennzeichnet dieses als Konstante (vergleiche „Konstanten“ weiteroben).

event Kennzeichnet ein Ereignis.

extern Der Modifikator extern weist den Compiler an, dass die Funktionalität dernachfolgenden Methode extern implementiert ist. Häufig wird derModifikator in Verbindung mit dem Attribut DllImport verwendet, um dieFunktionalität einer (veralteten) Win32 DLL zu verwenden.

internal* Der Zugriffsmodifikator internal legt fest, dass auf eine Klasse oder einMitglied einer Klasse nur innerhalb des aktuellen Projektes (Assembly)zugegriffen werden kann.

override Um ein Mitglied einer abgeleiteten Klasse zu überschreiben und somit eineneue oder geänderte Implementation zu hinterlegen, muss der Modifikatoroverride verwendet werden. Er stellt das Gegenstück zu virtual dar.

private* Der Zugriffsmodifikator kennzeichnet eine Klasse oder ein Element alsprivat. Private Elemente sind nur innerhalb Ihrer Definition gültig. Klassenkönnen nur lokal instanziiert und Klassenmitglieder nur innerhalb der Klasseangesprochen werden.

protected* Dieser Modifikator regelt ebenfalls den Zugriff auf ein Element und legt fest,dass auf das entsprechende Element nur innerhalb der aktuellen oder einerabgeleiteten Klasse zugegriffen werden kann.

public* Dieser Zugriffsmodifikator stellt das Gegenstück zu private dar und erlaubtden öffentlichen und unbeschränkten Zugriff auf das jeweilige Element.

readonly Definiert, dass die nachfolgende Variable nur gelesen werden kann. Dereinmalige Schreibzugriff zur Initialisierung der Variable ist bei derDeklaration oder innerhalb eines Klassen-Konstruktors möglich.

sealed Dieser Modifikator versiegelt eine Klasse und stellt somit sicher, dass keineanderen Klassen von dieser abgeleitet werden können.

static static kennzeichnet ein Mitglied einer Klasse als statisch. Dieses stehtdadurch global über den Klassennamen und nicht über die Instanz derKlasse zur Verfügung.

Page 65: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

3 Klassen & objektorientierte Programmierung – Teil I __________________________65

Modifikator Beschreibung

virtual Damit ein Klassen-Mitglied in einer abgeleiteten Klasse mit Hilfe vonoverride überschrieben werden kann, muss dieses Mitglied in derBasisklasse mit dem Modifikator virtual versehen werden. Wird dasMitglied nicht überschrieben, so wird in der abgeleiteten Klasse dieursprüngliche Implementation verwendet. In diesem Punkt unterscheidetsich der Modifikator von abstract, da das Mitglied überschrieben werdenkann, aber nicht muss.

unsafe Um Programmcode zu erzeugen, der nicht von der Common LanguageRuntime überprüft wird, ist der Modifikator unsafe notwendig. Innerhalb desnachfolgenden Elements kann unsicherer Code wie Zeiger verwendetwerden. Zur Verwendung des Modifikators muss zusätzlich die Compiler-Option /unsafe verwendet werden.

private und public

Die Mitglieder eine Klasse sind standardmäßig als privat gekennzeichnet. Imfolgenden Beispiel ist daher der Zugriff auf die Methode PrivateMethod nichtmöglich. Der externe Zugriff auf die Methode PublicMethod ist hingegen möglich,da diese explizit als öffentlich gekennzeichnet ist.

Listing 3.14 privatepublic1.cs

using System;

class Test{

public void PublicMethod(){}

void PrivateMethod(){}

}

class ConsoleApp{static void Main(){Console.ReadLine();}}

Page 66: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

66 _______________________________________ 3.5 Deklaration einer neuen Klasse

static

Um eine statisches Mitglied einer Klasse zu implementieren, muss dieses mit demModifikator static versehen werden. Der Unterschied zwischen dynamischen undstatischen Mitgliedern wurde bereits weiter oben ausführlich beschrieben. Hiernoch einmal ein kleines Beispiel, das den Unterschied deutlich macht.

Listing 3.15 static1.cs

using System;

class Test{

public static void StaticMethod(){}

public void InstanceMethod(){}}

class ConsoleApp{static void Main(){Console.ReadLine();}}

Der Aufruf der Methode StaticMethod erfolgt über den Klassennamen:

Test.StaticMethod();

Damit auf die dynamische Methode zugegriffen werden kann, muss zunächst eineInstanz der Klasse instanziiert werden:

Test objTest = new Test();objTest.InstanceMethod();

Page 67: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

3 Klassen & objektorientierte Programmierung – Teil I __________________________67

abstract, override, sealed und virtual

Diese Modifikatoren werden in Verbindung mit dem Ableiten oder Vererben vonKlassen verwendet. Eine ausführliche Beschreibung dieser Techniken finden Sie inden weitergehenden Möglichkeiten der objektorientierten Programmierung in C#unter der Überschrift „Klassen & objektorientierte Programmierung – Teil II“.

3.5.7 Konstruktor

Bei der Instanziierung einer Klasse wird automatisch eine Standard-Methode derKlasse aufgerufen. Diese Methode wird in der Regel verwendet, um initielleEinstellungen vorzunehmen, Variablen zu initialisieren und so weiter. DieseStandard-Methode hat den Namen der Klasse und wird Konstruktor genannt. WennIhre Klasse einer Initialisierung bedarf, dann können Sie jederzeit einenKonstruktor nach dem folgenden Schema implementieren:

class Test{public Test(){// Initialisierung der Klasse}}

Ihre wirkliche Leistungsfähigkeit entfalten Konstruktoren allerdings erst, wenn siemit Parametern versehen werden. Sie können neben dem Standard-Konstruktorbeliebig viele weitere Konstruktoren implementieren, die über jeweilsunterschiedliche Parameter verfügen. Man nennt dieses Vorgehen Überladen, eineweitergehende Beschreibung finden Sie unter „Klassen & objektorientierteProgrammierung – Teil II“.

Das Schema sieht in diesem Fall wie folgt aus:

class Test{public Test(){// Initialisierung der Klasse}

Konstruktor mitParameter

Page 68: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

68 _______________________________________ 3.5 Deklaration einer neuen Klasse

public Test(Datentyp Parameter){// Initialisierung der Klasse mit Parametern}}

Vielleicht erinnern Sie sich an das Beispiel der Katze, die ihren Namen nicht ändernwollte. Hierzu wurde weiter oben eine Eigenschaft mit get und set implementiert,bei der der Aufruf von set nur ein einziges Mal vorgenommen wurde. DieserAnsatz lässt sich mit einem überladenen Konstruktor sehr viel schöner lösen, wiedas nachfolgende Beispiel zeigt: Dem Konstruktor wird der Name der Katzeübergeben, der anschließend der lokalen Mitgliedsvariablen zugewiesen wird. DieEigenschaft Name wird nur mit get implementiert, so dass ein explizites Setzen desNamens gar nicht erst möglich ist.

Listing 3.16 class13.cs

using System;

class Katze{

string _Name;

public Katze(string Name){_Name = Name;}

public string Name{get{return(_Name);}}

}

class ConsoleApp{static void Main(){Katze meineKatze = new Katze("Filou");

Page 69: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

3 Klassen & objektorientierte Programmierung – Teil I __________________________69

Console.WriteLine("Meine Katze heißt: ");Console.WriteLine(meineKatze.Name + "");

Console.ReadLine();}}

Die Ausgabe im Konsolenfenster zeigt, dass der Parameter des Konstruktorskorrekt an die Eigenschaft übergeben wurde:

Meine Katze heißt: Filou

Wie beschrieben, lassen sich beliebig viele verschiedene Konstruktorenimplementieren. Die Unterscheidung erfolgt auf Basis einer individuellenParameter-Sequenz. Die Sequenz für den Standard-Konstruktor sind keineParameter. Die Sequenz im vorangegangenen Beispiel wäre ein Parameter vom Typstring. Sie können der Klasse natürlich weitere Konstruktoren hinzufügen, für dieeine andere Sequenz gelten. Der Compiler sucht sich jeweils den Konstruktorheraus, der für die beim Aufruf angegebene Parameter-Sequenz zutrifft. Imfolgenden Beispiel wird die Klasse Katze um zwei weitere Konstruktoren ergänzt.

Listing 3.17 class14.cs

using System;

class Katze{

string _Name;int _Zufriedenheitsindex;

public Katze(string Name){_Name = Name;}

public Katze(string Name, int Zufriedenheitsindex){_Name = Name;this.Zufriedenheitsindex = Zufriedenheitsindex;}

MehrereKonstruktoren

Page 70: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

70 _______________________________________ 3.5 Deklaration einer neuen Klasse

public Katze(int Zufriedenheitsindex){this.Zufriedenheitsindex = Zufriedenheitsindex;}

public string Name{get{return(_Name);}}

public int Zufriedenheitsindex{get{return(_Zufriedenheitsindex);}set{_Zufriedenheitsindex = value;}}

}

class ConsoleApp{static void Main(){Katze meineKatze = new Katze("Filou", 25);

Console.WriteLine("Meine Katze heißt: ");Console.WriteLine(meineKatze.Name + "");

Console.WriteLine("Der Zufriedenheitsindex liegt bei ");Console.WriteLine(meineKatze.Zufriedenheitsindex.ToString());

Console.ReadLine();}}

Die Klasse erlaubt nun neben der Angabe des Namens im Konstruktor auch dieÜbergabe des initiellen Zufriedenheitsindex. Insgesamt wurden hierzu dreiKonstruktoren übergeben. Einer nur für den Namen, einer nur für den Index undeiner für Name und Index. Im Beispiel-Aufruf der Klasse wurde Letztererverwendet. Die Ausgabe im Konsolenfenster sieht wie folgt aus:

Page 71: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

3 Klassen & objektorientierte Programmierung – Teil I __________________________71

Meine Katze heißt: FilouDer Zufriedenheitsindex liegt bei 25

Neben einem oder mehreren Konstruktoren für die Instanziierung einer Klasse stehtauch ein statischer Konstruktor zur Verfügung. Dieser wird ausgeführt, wenn eineKlasse das erste Mal benutzt wird. Der statische Konstruktor wird parallel zumdynamischen deklariert und über den Modifikator static gekennzeichnet. Demstatischen Konstruktor können keine Parameter übergeben werden.Das nachfolgende Beispiel zeigt einen statischen Konstruktor, der einer ebenfallsstatischen Mitgliedsvariable einen zufälligen Wert zuweist. Dieser Wert stehtübrigens auch über mehrere Seiten hinweg zur Verfügung. Dies ist so lange derFall, bis die Garbage Collection die Information aus dem Speicher entfernt.

Listing 3.18 class15.cs

using System;

class Test{

public static int RandomID;

static Test(){Random rnd = new Random();RandomID = rnd.Next();}

}

class ConsoleApp{static void Main(){Console.WriteLine("Die Klasse Test hat die RandomID: ");Console.WriteLine(Test.RandomID.ToString() + "");

Console.ReadLine();}}

StatischerKonstruktor

Page 72: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

72 _______________________________________ 3.5 Deklaration einer neuen Klasse

Die Ausgabe im Konsolenfenster ist ganz zufällig und sieht beispielsweise wie folgtaus:

Die Klasse Test hat die RandomID: 1195392319

3.5.8 Destruktor

Ein Destruktor ist quasi das Gegenstück zu einem Konstruktor. Es handelt sich umeine private Methode ohne Parameter, die bei der Terminierung einer Klasseaufgerufen wird. Der Destruktor wird für eventuell notwendige Aufräumarbeitenverwendet, beispielsweise zum Löschen von temporär angelegten Dateien, etc. DieDeklaration erfolgt ähnlich dem Konstruktor entsprechend dem folgenden Schema:

~Klassenname(){// Befehlszeilen

}

Es wird also auch hier der Name der Klasse für die Benennung der Methodeverwendet, allerdings diesmal mit einer Tilde ~ als Präfix zur Kennzeichnung desDestruktors. Beachten Sie, dass jede Klasse nur einen Destruktor implementierenund dieser nie Parameter enthalten kann.Das folgende Beispiel implementiert auf Basis der Klasse Katze eine statische,öffentliche Variable. Diese wird durch den Konstruktor der Klasse inkrementiertund durch den Desktrukor dekrementiert. Auf diese Weise kann über dieEigenschaft die Anzahl der instanziierten Klassen abgefragt werden und so indiesem Beispiel die Anzahl der Katzen.

Listing 3.19 class16.cs

using System;

class Katze{

public static int Anzahl = 0;

public string Name;

public Katze(){Anzahl++;}

Page 73: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

3 Klassen & objektorientierte Programmierung – Teil I __________________________73

~Katze(){Anzahl--;}

}

class ConsoleApp{static void Main(){Katze meineKatze1 = new Katze();Katze meineKatze2 = new Katze();

Console.WriteLine("Ich habe insgesamt ");Console.WriteLine(Katze.Anzahl.ToString() + " Katzen");

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Ich habe insgesamt 2 Katzen

Bereits bei der Erklärung zur Terminierung einer Klasse wurde auf die GarbageCollection hingewiesen. Diese übernimmt das Aufräumen des Speichers und ist indiesem Sinne verantwortlich für den Aufruf des Destruktors. Dieser wird also erstdann aufgerufen, wenn die Gargabe Collection den Speicher der Klasse freigibt.Dies ist typischerweise in Leerlaufzeiten des Rechners oder bei akutemSpeicherplatzbedarf der Fall. Das folgende Beispiel demonstriert dies sehranschaulich.

Listing 3.20 class17.cs

// Klassenimplementation analog zu class15.cs

...

Katze meineKatze1 = new Katze();Katze meineKatze2 = new Katze();Katze meineKatze3 = new Katze();

Console.WriteLine("Ich habe insgesamt ");Console.WriteLine(Katze.Anzahl.ToString() + " Katzen");

meineKatze3 = null;

GarbageCollection

Page 74: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

74 _______________________________________ 3.5 Deklaration einer neuen Klasse

Console.WriteLine("Ich habe insgesamt ");Console.WriteLine(Katze.Anzahl.ToString() + " Katzen");

Es werden zunächst drei Instanzen der Klasse Katze instanzziert und anschließenddie Eigenschaft Anzahl ausgegeben. Nun wird eine der Instanzen terminiert. Manwürde erwarten, dass sich die Eigenschaft Anzahl nun entsprechend verkleinert,doch ist das nicht der Fall, da die Garbage Collection noch keine Zeit hatte, denSpeicher aufzuräumen. Die Anzahl bleibt daher unverändert, wie die Ausgabe imKonsolenfenster zeigt:

Ich habe insgesamt 3 KatzenIch habe insgesamt 3 Katzen

Dieser Zustand kann übrigens länger andauern. Sie sollten daher unbedingt daraufachten, dass Sie vorsichtig mit dem Destruktor umgehen und diesem keinezeitkritischen Aufgaben überlassen. Von einer Verwendung als Zähler wie indiesem Beispiel sei daher ausdrücklich abgeraten.

3.5.9 Attribute

C# beziehungsweise das .NET Framework bieten mit Attributen eine Möglichkeit,einer Klassen oder auch nur einzelnen Mitgliedern dieser Klasse standardisierteEigenschaften mitzugeben. Diese Meta-Daten können unterschiedlichsteInformationen enthalten, die das jeweilige Element in einer bestimmten Hinsichtnäher beschreiben. Die Angabe dieser Informationen erfolgt über so genannteAttribute. Attribute werden vor der Deklaration des jeweiligen Elements in eckigenKlammern notiert:

[AttributName(Parameter)]class Klassenname{[AttributName(Parameter)]Modifikator Datentyp Methodennamen{// Befehlszeilen}}

Einsatzgebiete für Attribute gibt es wie Sand am Meer. Diese werden entwederdurch das .NET Framework vorgegeben oder individuell angelegt. Attribute könnennicht nur zur Entwicklungszeit im Programmcode hinterlegt werden, sondern auchspäter über Reflections (vergleiche gleichnamiges Kapitel weiter unten) angelegt

Reflections

Page 75: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

3 Klassen & objektorientierte Programmierung – Teil I __________________________75

werden. Auch ein lesender Zugriff sowie die Manipulation von Attributen ist überReflections möglich.Einige Beispiele für im .NET Framework fest integrierte Attribute sind dasConditionalAttribute zur bedingten Ausführung von Programmcode, dasObsoleteAttribute zur Kennzeichnung von veraltetem Programmcode, dasWebServiceAttribute zur Veröffentlichung von Mitgliedern als WebServices und soweiter. Per Definition werden alle Attribute in der Form „NameAttribute“ benannt.In C# ist allerdings nur die Angabe des Namens, ohne das abschließende„Attribute“, notwendig.Um einen Programmbereich als veraltet zu kennzeichnen, können Sie das folgendeBeispiel anwenden:

Listing 3.21 attribute1.cs

using System;

class Test{[Obsolete("Veraltete Methode, bitte NeueMethode() verwenden!")]public void AlteMethode(){}

public void NeueMethode(){}}

class ConsoleApp{static void Main(){Console.ReadLine();}}

Verwendet man die alte Methode, würde der Compiler einen Warnungstextausgeben. Würde man hingegen den zweiten booleschen Parameter des Attributesmit true übergeben, würde der Compiler einen Fehler melden und die Verwendungder neuen Methode erzwingen.

Page 76: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2
Page 77: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

4Bedingungen

Das if-Konstrukt

Das switch-Konstrukt

Bedingungsoperator

Page 78: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

78 ____________________________________________________________________

Inhaltsübersicht Kapitel 4

4 Bedingungen.......................................................................................................79

4.1 Das if-Konstrukt ..................................................................................................794.2 Das switch-Konstrukt ..........................................................................................824.3 Bedingungsoperator.............................................................................................86

Page 79: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

____________________________________________________________________ 79

4 Bedingungen

Nahezu jedes Programm kommt an den Punkt, da es eine Entscheidung treffenmuss. Ob es sich um die Auswertung einer Benutzereingabe oder um die Anzahlvon Einträgen in einer Datenbank handelt. C# stellt zur Erstellung solcher Abfragenoder Bedingungen verschiedene Konstrukte zur Verfügung.

4.1 Das if-Konstrukt

Mit dem if-Konstrukt lassen sich einfache Wenn..Dann-Bedingungen realisieren. Eswird dabei ein boolescher Ausdruck, also die kleinste mögliche Informationausgewertet: ja oder nein. Die folgenden Zeilen zeigen bereits eine solcheBedingung:

Listing 4.1 if1.cs

using System;

class ConsoleApp{static void Main(){int i = 1;

if(i==1)Console.WriteLine("i entspricht 1");

Console.ReadLine();}}

Zunächst wird die Variable i mit dem Wert 1 initialisiert. Nun erfolgt die Abfrageder Bedingung mit Hilfe des Schlüsselwortes if(). Die überprüfende Bedingungwird in Klammern hinter das Schlüsselwort gesetzt. Falls die Bedingung zutrifft,wird die anschließend angegebene Aktion ausgeführt. In diesem Fall wird der Text„i entspricht 1“ im Konsolenfenster ausgegeben.

Page 80: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

80 ___________________________________________________ 4.1 Das if-Konstrukt

Sollen statt nur einer Aktion gleich mehrere aufgerufen werden, wenn dieBedingung zutrifft, so werden diese Aktionen einfach mit geschweiften Klammerneingeklammert.

Listing 4.2 if2.cs

using System;

class ConsoleApp{static void Main(){int i = 1;

if(i==1){Console.WriteLine("i entspricht 1");Console.WriteLine("");Console.WriteLine("Schwups, sind wir in der nächsten Zeile");}

Console.ReadLine();}}

Die Anforderungen an eine Abfrage sind ganz unterschiedlich und häufig nicht sosimpel, wie in den vorherigen Fällen. Soll beispielsweise eine alternative Aktiondurchgeführt werden, falls die Bedingung nicht zutrifft, kann das Schlüsselwortelse verwendet werden. Dieses wird einfach im Anschluss an das bestehendeKonstrukt angeführt.

Listing 4.3 if3.cs

using System;

class ConsoleApp{static void Main(){int i = 2;

if(i==1)Console.WriteLine("i entspricht 1");elseConsole.WriteLine("i entspricht leider nicht 1");

Console.ReadLine();}}

if..else

Page 81: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

4 Bedingungen _________________________________________________________81

Die Ausgabe dieses Beispiels würde „i entspricht leider nicht 1“ lauten. Auch hierkönnen mehrere Aktionen durchgeführt werden, indem diese entsprechendeingeklammert werden.

Listing 4.4 if4.cs

using System;

class ConsoleApp{static void Main(){int i = 2;

if(i==1){Console.WriteLine("i entspricht 1");}else{Console.WriteLine("i entspricht leider nicht 1");Console.WriteLine("");Console.WriteLine("Das geht auch bei else");}

Console.ReadLine();}}

Bisher bezogen sich die Abfragen immer auf eine Bedingung. Es lassen sich aberauch sequenziell mehrere Bedingungen abfragen. Hierzu wird hinter dem elseeinfach ein neues if() angeführt. Beachten Sie hierbei, dass es aus rein logischenGründen nur ein einziges else ohne zusätzliche Angabe einer Bedingung gebenkann.

Listing 4.5 if5.cs

using System;

class ConsoleApp{static void Main(){int i = 2;

if(i==1)Console.WriteLine("i entspricht 1");else if(i==2)Console.WriteLine("i entspricht 2");

if..else if..else

Page 82: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

82 _______________________________________________ 4.2 Das switch-Konstrukt

elseConsole.WriteLine("i entspricht weder 1 noch 2");

Console.ReadLine();}}

Zunächst erfolgt ein Vergleich der Variable i mit dem Wert 1. Stimmt 1 nicht mit 1überein, erfolgt ein Vergleich mit 2. Trifft dies ebenfalls nicht zu, wird schließlichdie alternative Aktion ausgeführt.

4.2 Das switch-Konstrukt

if()..else if()..else-Konstrukte lassen sich beliebig tief verlängern. Dies ist aberweder übersichtlich noch besonders schnell. Insbesondere wenn eine Variable mitmehreren möglichen Werten verglichen werden soll, bietet sich das switch-Konstrukt an. Umgesetzt auf dieses Konstrukt sieht das vorangegangene Beispielwie folgt aus:

Listing 4.6 switch1.cs

using System;

class ConsoleApp{static void Main(){int i = 2;

switch(i){case 1:Console.WriteLine("i entspricht 1");break;

case 2:Console.WriteLine("i entspricht 2");break;

case, break unddefault

Page 83: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

4 Bedingungen _________________________________________________________83

default:Console.WriteLine("i entspricht weder 1 noch 2");break;

}

Console.ReadLine();}}

Der Ablauf erscheint bereits auf den ersten Blick übersichtlicher und bringt dankinterner Optimierungsmöglichkeiten wie zum Beispiel Hashtables einenPerformance-Gewinn.Zunächst wird hinter dem Schlüsselwort switch die Variable genannt, dieverglichen werden soll. Nun folgen eingeklammert die möglichen Vergleichswerte,jeweils eingeleitet durch Schlüsselwort case. Dahinter folgen die auszuführendenAktionen, die durch das Schlüsselwort break abgeschlossen werden müssen. Dieoptionale Standard-Aktion kann (analog zu else) hinter dem Schlüsselwortdefault folgen. Sofern in einem Block mehrere Aktionen ausgeführt werdensollen, müssen diese übrigens nicht eingeklammert werden.Soll eine identische Aktion bei mehreren möglichen Vergleichswerten ausgeführtwerden, so können die einzelnen case-Anweisungen einfach hintereinanderaufgeführt werden. Das Schlüsselwort break wird dabei weggelassen, so dass dasProgramm quasi durch die Vergleiche „durchfallen“ kann.

Listing 4.7 switch2.cs

using System;

class ConsoleApp

{

static void Main()

{

int i = 2;

switch(i){case 1:case 2:Console.WriteLine("i entspricht 1 oder 2");break;

default:

Mehrere Fälle

Page 84: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

84 _______________________________________________ 4.2 Das switch-Konstrukt

Console.WriteLine("i entspricht weder 1 noch 2");break;

}

Console.ReadLine();}}

Alternativ sind innerhalb eines switch-Konstruktes auch absolute Sprünge möglich.Dabei kann entweder zu einem anderen case-Block oder zum default-Blockgesprungen werden. In beiden Fällen wird die Anweisung goto verwendet („Gehezu“).

Listing 4.8 switch3.cs

using System;

class ConsoleApp{static void Main(){int i = 2;

switch(i){case 1:Console.WriteLine("i entspricht 1 oder 2");break;

case 2:goto case 1;break;

case 3:goto default;

default:Console.WriteLine("i entspricht weder 1 noch 2");break;

}

Console.ReadLine();}}

Funktionell entspricht dieses Beispiel dem vorangegangenen. Entspricht i 1 oder 2,wird letztlich der case 1 Block ausgeführt, in jedem anderen Fall der default-Block.

Sprünge

Page 85: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

4 Bedingungen _________________________________________________________85

Sofern i dabei 2 oder 3 entspricht, wird ein kleiner Umweg über einen separatenBlock eingelegt, um von dort zu einem anderen zu springen.Anders als bei C++ kann das switch-Konstrukt in C# auch in Verbindung mitZeichenketten eingesetzt werden. Im Folgenden wird ein Sprach-Code verglichenund die korrespondierende Sprache im Klartext ausgegeben.

Listing 4.9 switch4.cs

using System;

class ConsoleApp{static void Main(){string sLangCode = "de";string sLangName;

switch(sLangCode){case "de":sLangName = "Deutsch";break;

case "en":sLangName = "Englisch";break;

default:sLangName = "Unbekannt";break;

}

Console.WriteLine("Der Sprachen-Code \"" + sLangCode +"\" entspricht der folgenden Sprache: " + sLangName + ".");

Console.ReadLine();}}

Interessant zu sehen ist hierbei die gelungene Unterstützung des C# Compilersgegenüber anderen Sprachen. Würde man beispielsweise die Zuweisung derVariable sLangName in einem beliebigen der drei case-Blöcke entfernen, würde eszu einem Compiler-Fehler kommen. Es würde so nämlich die Möglichkeitbestehen, dass die Variable nicht initialisiert ist, wenn sie weiter unten verwendetwird. Durch den zusätzlichen default-Block im vorliegenden Beispiel ist dies injedem Fall gewährleistet. Diese und andere Sicherheiten schützen den Entwickler

switch mitZeichenketten

Page 86: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

86 ________________________________________________ 4.3 Bedingungsoperator

vor vielen Standard-Fehlern, die bei anderen Sprachen wie C und C++ häufig erstwährend der Ausführung (beim Kunden?) bemerkt werden.

4.3 Bedingungsoperator

Der Bedingungsoperator ist ein Operator und daher eigentlich besser im Kapitel„Operatoren“ aufgehoben. Der Operator kann jedoch in einigen Fällen alsAlternative zur if-Bedingung verwendet werden und bedarf daher auch an dieserStelle der Erwähnung.Das Konstrukt arbeitet als Operator „inline“, also innerhalb einer Zeile, und liefertwie eine Funktion einen Wert zurück.

Listing 4.10 Bedingungsoperator1.cs

int i = 1;

Console.WriteLine("i entspricht " + ((i==1) ? "1" : "nicht 1"));

Das Beispiel gibt im Konsolenfenster den Text „i entspricht 1“ aus und entsprichtfunktionell dem einfachen, weiter oben skizzierten if..else-Beispiel. Zunächstwerden in Klammern die Bedingungen notiert. Anschließend folgt ein Fragezeichenund der Wert, der zurückgeliefert werden soll, wenn die Bedingung zutrifft. Ist diesnicht der Fall, wird der nach einem Doppelpunkt notierte Wert zurückgeliefert.Auch wenn der Bedingungsoperator sicherlich die ein oder andere Zeile Tipparbeitspart, ist dieser doch unübersichtlich und somit schwer zu lesen. Es gibt sicherlichsinnvolle Einsatzgebiete, eine übermäßige Benutzung sollte aber zu Gunsten derbesseren Lesbarkeit vermieden werden.

Page 87: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

5Schleifen

Die for-Schleife

Die while-Schleife

Die do-Schleife

Die foreach..in-Schleife

Die Anweisungen break und continue

Page 88: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

88 ____________________________________________________________________

Inhaltsübersicht Kapitel 5

5 Schleifen .............................................................................................................89

5.1 Die for-Schleife ...................................................................................................895.2 Die while-Schleife ...............................................................................................915.3 Die do-Schleife ....................................................................................................925.4 Die foreach..in-Schleife .......................................................................................925.5 Die Anweisungen break und continue .................................................................94

Page 89: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

____________________________________________________________________ 89

5 Schleifen

Schleifen sind ein unverzichtbares Element moderner Programmiersprachen. Sieermöglichen es, sich wiederholende Aktionen durchzuführen während (und nichtwenn!), eine Bedingung erfüllt ist. Schleifen werden im Deutschen häufig mit demSchlüsselwort „Solange“ übersetzt.

5.1 Die for-Schleife

Die for-Schleife eignet sich besonders gut zum Durchlaufen von Werten. Häufigwird die for-Schleife auch als Iteration bezeichnet. Der Iterator ist dabei fast immerein Integer-Wert, der inkrementiert wird.Dem Schlüsselwort for folgen drei Parameter: 1. Initialisierung, 2. Bedingung und3. Iteration. Die im ersten Parameter initialisierte Variable wird, wie im drittenParameter beschrieben, iteriert, solange die Bedingung im zweiten Parameterzutrifft. Ein einfaches Beispiel:

Listing 5.1 for1.cs

using System;

class ConsoleApp{static void Main(){for(int i=1; i<=10; i=i+1)Console.WriteLine("i entspricht " + i + "");

Console.ReadLine();}}

Iterator

Page 90: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

90 ____________________________________________________ 5.1 Die for-Schleife

Die Variable i wird mit dem Wert 1 intialisiert und so lange um 1 inkrementiert,wie diese kleiner oder gleich 10 ist. Letztlich wird die Schleife dadurch 10 maldurchlaufen. Das Beispiel gibt folgenden Text im Konsolenfenster aus:

i entspricht 1i entspricht 2i entspricht 3i entspricht 4i entspricht 5i entspricht 6i entspricht 7i entspricht 8i entspricht 9i entspricht 10

Die oben verwendete Schreibweise für den Iterator ist übrigens absolut unüblich, daC# hier eine sehr schöne Kurform in Form von speziellen Operatoren anbietet. EinBeispiel hierfür sind die Operatoren ++ beziehungsweise --, die eine zuvor notierteVariable um eins inkrementieren beziehungsweise dekrementieren. Üblicherweisewürde man das obige Beispiel daher wie folgt notieren.

Listing 5.2 for2.cs

using System;

class ConsoleApp{static void Main(){for(int i=1; i<=10; i++)Console.WriteLine("i entspricht " + i + "");

Console.ReadLine();}}

Selbstverständlich können auch mehrere Aktionen innerhalb der Schleifedurchgeführt werden. Hierzu werden diese nach dem Schlüsselwort for geschweifteingeklammert.

Listing 5.3 for3.cs

using System;

class ConsoleApp{static void Main(){

Page 91: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

5 Schleifen ____________________________________________________________91

for(int i=1; i<=10; i++){Console.WriteLine("i entspricht ");Console.WriteLine(i.ToString());Console.WriteLine("");}

Console.ReadLine();}}

5.2 Die while-Schleife

While bedeutet übersetzt „so lange“ und trifft die deutsche Bezeichnung vonSchleifen daher am ehesten. Die Schleife wird ausgeführt, solange eine Bedingungzutrifft und verzichtet auf jeglichen zusätzlichen Komfort wie eine integrierteIteration. while lässt sich daher universell einsetzen und somit kann auch dasBeispiel der einfachen for-Schleife mit while realisiert werden.

Listing 5.4 while1.cs

using System;

class ConsoleApp{static void Main(){int i = 1;

while(i<=10){Console.WriteLine("i entspricht " + i + "");i++;}

Console.ReadLine();}}

Solange die Variable i einen Wert kleiner oder gleich 10 enthält, wird die Schleifeausgeführt. Innerhalb dieser wird dann erneut der ++ Operator zur Inkrementierungder Variable verwendet.

Page 92: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

92 ____________________________________________________ 5.3 Die do-Schleife

5.3 Die do-Schleife

Die do-Schleife arbeitet analog zu while, allerdings wird die Bedingung hierbei amEnde der Schleife ausgewertet. Infolgedessen wird diese Schleife immer mindestenseinmal durchlaufen, egal ob die Bedingung zutrifft oder nicht. Umgesetzt sähe dasvorangegangene Beispiel wie folgt aus.

Listing 5.5 do1.cs

using System;

class ConsoleApp{static void Main(){int i = 1;

do{Console.WriteLine("i entspricht " + i + "");i++;} while(i<=10);

Console.ReadLine();}}

Der Unterschied wird erst richtig auffällig, wenn man die Variable i mit dem Wert11 initialisiert. Die while-Schleife (vergleiche while2.cs) würde in diesem Fallkeinerlei Ausgaben erzeugen, da die Bedingung (<=10) nicht zutrifft. Die do-Schleife hingegen hat folgendes Ergebnis.

i entspricht 11

5.4 Die foreach..in-Schleife

Die foreach..in-Schleife wird zum Durchlaufen aller Elemente einer Kollektion oderArrays verwendet. Die deutsche Übersetzung bringt es auf den Punkt: „... für jedes[Element] in ...“ Auf diese Weise lassen sich sehr viele unterschiedliche ArtenKollektionen ansprechen, doch nicht alle. Der Grund hierfür ist, dass dieseKollektionen bestimmte Schnittstellen unterstützen müssen, die von der foreach..in-Schleife verwendet werden. Mehr zu Kollektionen und Arrays finden Sie imAbschnitt „Arrays“ im Kapitel „Erweiterte Datentypen“.

Page 93: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

5 Schleifen ____________________________________________________________93

Listing 5.6 foreach1.cs

using System;

class ConsoleApp{static void Main(){string[] sArray = new string[10];

for(int i=0; i<sArray.Length; i++)sArray[i] = "Array-Element Nummer " + (i+1);

foreach(string s in sArray)Console.WriteLine(s + "");

Console.ReadLine();}}

Die Ausgabe dieses Beispieles im Konsolenfenster sieht wie folgt aus:

Array-Element Nummer 1Array-Element Nummer 2Array-Element Nummer 3Array-Element Nummer 4Array-Element Nummer 5Array-Element Nummer 6Array-Element Nummer 7Array-Element Nummer 8Array-Element Nummer 9Array-Element Nummer 10

Das Beispiel definiert zunächst ein neues Zeichenfolgen-Array mit 10 Elementen.Mit Hilfe einer normalen for-Schleife wird jedes Element des Arrays mit einerZeichenkette gefüllt. Anschließend wird eine foreach..in-Schleife verwendet, umden Inhalt wieder auszulesen und im Konsolenfenster auszugeben. Es wird dabeider Unterschied zwischen der for- und der foreach..in-Schleife deutlich. Benötigtman im ersten Fall noch genaue Informationen über den Aufbau, dieZugriffsmöglichkeit und die Dimension, sind diese Angaben im zweiten Fall nichtmehr notwendig. Auch kann auf die zusätzliche Definition einer Index-Variable (i)verzichtet werden. Die foreach..in-Schleife ist somit komfortabler undübersichtlicher zu lesen. Selbstverständlich ist wie gewohnt durch Einklammerungdie Ausführung mehrerer Aktionen problemlos möglich.

Page 94: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

94 __________________________________ 5.5 Die Anweisungen break und continue

Viele vom .NET Framework zur Verfügung gestellten Informationen werden inKollektionen angeboten und ermöglichen somit den Zugriff über eine foreach..in-Schleife. Die folgenden Zeilen demonstrieren die Ausgabe einer zuvor erstelltenHasttable über eine foreach..Schleife.

Listing 5.7 foreach2.cs

using System;using System.Collections;

class ConsoleApp{static void Main(){Hashtable ht = new Hashtable();ht.Add("Wort 1", "Hallo");ht.Add("Wort 2", "Welt");ht.Add("Wort 3", "!");

foreach(string s in ht.Keys)Console.WriteLine(s + " = " + ht[s] + "");

Console.ReadLine();}}

5.5 Die Anweisungen break und continue

Die Flexibilität der vorgestellten Schleifen wird durch zwei zusätzlicheSchlüsselwörter erweitert, die in jeder Schleifenart verwendet werden können.Die Anweisung break dient zum vorzeitigen, vollständigen Verlassen einerSchleife. In der Regel steht der Anweisung eine Bedingung vor.

Listing 5.8 break1.cs

using System;

class ConsoleApp{static void Main(){for(int i=1; i<=10; i++){if(i==4)break;Console.WriteLine("i entspricht " + i + "");

break

Page 95: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

5 Schleifen ____________________________________________________________95

}

Console.ReadLine();}}

Bei jedem Durchlauf der Schleife wird der Inhalt der Variablen i verglichen.Stimmt diese mit 4 überein, wird die Anweisung break aufgerufen. Das Ergebnis imKonsolenfenster sieht daher wie folgt aus.

i entspricht 1i entspricht 2i entspricht 3

Ähnlich wie die break-Anweisung arbeitet auch continue. Allerdings wird beidieser Anweisung lediglich die aktuelle Iteration unterbrochen und mit derfolgenden fortgefahren.

Listing 5.9 continue1.cs

using System;

class ConsoleApp{static void Main(){for(int i=1; i<=10; i++){if(i%2==0)continue;Console.WriteLine("i entspricht " + i + "");}

Console.ReadLine();}}

Wie könnte wohl die Ausgabe dieser Schleife aussehen? Der Operator % berechnetden Restbetrag (Modulo) einer Division. i%2==0 trifft also für alle geraden Wertezu. Das Ergebnis im Konsolenfenster ist daher folgerichtig auf die Ausgabe derungeraden Werte beschränkt.

i entspricht 1i entspricht 3i entspricht 5i entspricht 7i entspricht 9

continue

Page 96: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2
Page 97: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

6Sprunganweisungen

break

continue

goto

return

throw

Page 98: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

98 ____________________________________________________________________

Inhaltsübersicht Kapitel 6

6 Sprunganweisungen...........................................................................................99

6.1 break ....................................................................................................................996.2 continue ...............................................................................................................996.3 goto....................................................................................................................1006.4 return .................................................................................................................1016.5 throw..................................................................................................................102

Page 99: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

____________________________________________________________________ 99

6 Sprunganweisungen

C# kennt fünf verschiedene Anweisungen, die einen Sprung derProgrammausführung vom aktuellen zu einem zu definierenden Standpunkterlauben. Die meisten Sprunganweisungen wurden bereits im Verlaufe des Buchesim jeweiligen Kontext angesprochen. Diese Übersicht fasst sie noch einmalzusammen.

6.1 break

Die Sprunganweisung break wird verwendet, um die Durchführung von Schleifenzu unterbrechen. Die Schleife wird dabei unabhängig vom aktuellen Statuskomplett abgebrochen und die Programmausführung beim ersten Befehl nach derSchleife fortgesetzt. Ein Beispiel hierzu finden Sie in „Die Anweisungen break undcontinue“.Ein zweites Einsatzgebiet der Sprunganweisung break ist das switch-Konstrukt.Hierbei muss für jeden möglichen Vergleichsfall (Schlüsselwort case) die break-Anweisung notiert werden. Ein Beispiel hierzu finden Sie in „Das switch-Konstrukt“.

6.2 continue

Auch die continue-Anweisung wird innerhalb von Schleifen verwendet. ImGegensatz zur break-Anweisung wird die Schleife jedoch nicht komplett verlassen,sondern lediglich der aktuelle Durchlauf beendet und mit dem nächsten fortgesetzt.Ein Beispiel hierzu finden Sie ebenfalls in „Die Anweisungen break und continue“.

Page 100: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

100 ____________________________________________________________ 6.3 goto

6.3 goto

goto erlaubt den direkten Sprung an eine notierte Position. Diese Position, genanntLabel, wird an einer beliebigen Stelle im gleichen Geltungsbereich gefolgt voneinem Doppelpunkt notiert. Die Anweisung goto gefolgt vom Namen der Positionspringt die Position an.

Listing 6.1 goto1.cs

using System;

class ConsoleApp{static void Main(){goto meinlabel;

Console.WriteLine("Dieser Text wird niemals ausgegeben");

meinlabel:

Console.WriteLine("Dieser schon :-)");

Console.ReadLine();}}

Zu beachten ist dabei, dass sich beide Anweisungen innerhalb einesGültigkeitsbereiches befinden. Man kann beispielsweise nicht in eine Schleife oderBedingung hinein springen.

Listing 6.2 goto2.cs

using System;

class ConsoleApp{static void Main(){goto meinlabel;

Console.WriteLine("Dieser Text wird niemals ausgegeben");

for(int i=1; i<=10; i++){meinlabel:Console.WriteLine("Dieser schon :-)");}

Page 101: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

6 Sprunganweisungen __________________________________________________101

Console.ReadLine();}}

Dieses Beispiel wird mit einem Fehler quittiert, da die Position „meinlabel“ nichtim Gültigkeitsbereich der goto-Anweisung gefunden werden kann.

Abbildung 6.1 Ein Sprung in einen anderen Gültigkeitsbereich quittiert der C#-Compiler miteiner Fehlermeldung – Recht hat er.

Eine weitere Möglichkeit zur Verwendung von goto bietet das switch-Konstrukt.Hier kann zu einem angegebenen Vergleichsfall (case) oder dem Standardfall(default) gesprungen werden. Ein Beispiel hierzu finden Sie in „Das switch-Konstrukt“.Von der Verwendung der goto-Anweisung sei an dieser Stelle ausdrücklichgewarnt. Man sollte diese nur in größter Not und in Ausnahmefällen benutzen.Ansonsten kann es sehr schnell zu unübersichtlichem Code kommen, der oft alsSpagetti-Code bezeichnet wird. Folgt man streng den Regeln der objektorientiertenProgrammierung, ist der Befehl ohnehin überflüssig.

6.4 return

Mit return kann die Ausführung der aktuellen Prozedur oder Funktion unterbrochenund zur Position des Aufrufes zurückgekehrt werden. Bei Funktionen wird überdiese Anweisung zudem der Rückgabewert gemeldet. Der Aufruf der Anweisung istdaher zwingend erforderlich.

Page 102: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

102 ___________________________________________________________ 6.5 throw

Das folgende Beispiel enthält eine Prozedur Write, die eine übergebeneZeichenkette an die Methode WriteLine des Console-Objektes weitergibt. Für denFall, dass die übergebene Zeichenkette leer, also die Länge gleich 0 ist, wird dieAbarbeitung der Prozedur abgebrochen.

private void Write(string text){if(text.Length == 0 )return;

Console.WriteLine(text);}

...

Write("hallo welt");Write("");

6.5 throw

Diese Anweisung „wirft“ eine Ausnahme, also einen Fehler, und springt so weit imProgramm nach oben, bis eine entsprechende Ausnahmebehandlung gefunden wird.Eine ausführliche Beschreibung der Anweisung finden Sie im Kapitel„Fehlerbehandlungen“.

Page 103: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

7Operatoren

Mathematische Standard-Operatoren

Mathematische Kurz-Operatoren

Zuweisungsoperatoren

Noch mehr Mathematik mit der Klasse System.Math

Logische Operatoren

Typenoperatoren

Page 104: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

104 ___________________________________________________________________

Inhaltsübersicht Kapitel 7

7 Operatoren .......................................................................................................105

7.1 Mathematische Standard-Operatoren.................................................................1057.2 Mathematische Kurz-Operatoren.......................................................................1087.3 Zuweisungsoperatoren.......................................................................................1107.4 Noch mehr Mathematik mit der Klasse System.Math .......................................1127.5 Logische Operatoren..........................................................................................1157.5.1 Vergleichsoperatoren.........................................................................................1157.5.2 Verknüpfungsoperatoren ...................................................................................1167.5.3 Negationsoperator..............................................................................................1187.5.4 Bitweise (binäre) Operatoren.............................................................................1187.6 Typenoperatoren................................................................................................1237.6.1 typeof.................................................................................................................1237.6.2 is ........................................................................................................................1267.6.3 as........................................................................................................................1277.6.4 is versus as.........................................................................................................128

Page 105: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

___________________________________________________________________ 105

7 Operatoren

Der Syntax der C# Operatoren richtet sich ganz nach C++. Wer in dieser Sprachebereits Erfahrungen gesammelt hat, kann dieses Unterkapitel daher getrostüberspringen. Alle anderen, gerade auch Visual Basic– oder VBScript-Entwickler,werden hier einige interessante, weil komfortable Konstrukte entdecken.

7.1 Mathematische Standard-Operatoren

Natürlich kann C# rechnen und beherrscht alle Grundrechenarten aus dem Effeff.Die Addition zweier Werte erfolgt mit dem Plus-Zeichen „+“, die Subtraktion mit„–“, die Multiplikation mit „*“ und die Division mit „/“. Ein einfache Addition mitdem Plus-Operator sieht zum Beispiel wie folgt aus:

Listing 7.1 addition.cs

using System;

class ConsoleApp{static void Main(){int n1 = 1;int n2 = 2;int n3;

n3 = n1+n2;

Console.WriteLine("Das Ergebnis lautet ");Console.WriteLine(n3.ToString());

Console.ReadLine();}}

Addition

Page 106: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

106 _________________________________ 7.1 Mathematische Standard-Operatoren

Das Ergebnis dieses Beispiels ist – natürlich – 3. Die drei anderenGrundrechenarten lassen sich analog verwenden. Bei der Division muss beachtetwerden, dass bei Nachkommastellen der jeweils genaueste Datentyp für dieBerechnung und das Ergebnis verwendet wird.

Listing 7.2 division1.cs

using System;

class ConsoleApp{static void Main(){int n1 = 15;int n2 = 4;

Console.WriteLine("Das Ergebnis lautet ");Console.WriteLine((n1/n2).ToString());

Console.ReadLine();}}

Das Ergebnis dieses Beispiels ist 3, also die Ganzzahl der Berechnung, da derDatentyp int keine Nachkommastellen unterstützt. Ganz anders hingegen derDatentyp double. Dementsprechend ist das (mathematisch richtige) Ergebnis derBerechnung in diesem Fall 3,75. Im Übrigen folgt die .NET zu Grunde liegendeCommon Language Runtime bei der Berechnung von Gleitkommawerten den inIEEE 754 beschriebenen Regeln.

Listing 7.3 division2.cs

using System;

class ConsoleApp{static void Main(){double n1 = 15;int n2 = 4;

Console.WriteLine("Das Ergebnis lautet ");Console.WriteLine((n1/n2).ToString());

Console.ReadLine();}}

Division

Page 107: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

7 Operatoren _________________________________________________________107

Selbstverständlich werden auch mathematische Regelungen wie die Punkt-vor-Strich-Rechnung sowie die Klammerungen unterstützt. Es werden hierzu dienormalen Klammern „(“ und „)“ verwendet. Eine etwas „komplexere“ Berechnungkönnte beispielsweise so aussehen:

Listing 7.4 komplex1.cs

using System;

class ConsoleApp{static void Main(){int n = 1 + 3 * 5 - ((2 + 8) / 2);

Console.WriteLine("Das Ergebnis lautet ");Console.WriteLine(n.ToString());

Console.ReadLine();}}

Welches Ergebnis erzielen Sie aus dieser Berechnung? C# kennt sich aus in derMathematik und hält 11 für die richtige Antwort.Neben den regulären Grundrechenarten kennt C# auch die Berechnung desRestbetrages einer Division. Man nennt diese Berechnung Modulo. Als Operator-Zeichen wird hierzu „%“ verwendet Ein Beispiel:

Listing 7.5 modulo1.cs

using System;

class ConsoleApp{static void Main(){int n1 = 123;int n2 = 10;int n3;

n3 = n1%n2;

Console.WriteLine("Der Restbetrag lautet ");Console.WriteLine(n3.ToString());

Console.ReadLine();}}

Modulo

Page 108: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

108 _____________________________________ 7.2 Mathematische Kurz-Operatoren

Das Ergebnis der Modulo-Berechnung ist 3, denn 123 dividiert durch 10 ergibteinen nicht teilbaren Restbetrag von 3.

Tabelle 7.1 Die mathematischen Standard-Operatoren in der Übersicht

Operator Beschreibung

+ Addition

– Subtraktion

* Multiplikation

/ Division

% Modulo (Restbetrag)

7.2 Mathematische Kurz-Operatoren

Mit mathematischen Kurz-Operatoren lassen sich häufig benötigte mathematischeOperatoren komfortabel vereinfachen. Wie oft verwenden Sie die Variable i, umdiese in einer Schleife zu inkrementieren. Das könnte in C# beispielsweise wie folgtaussehen:

Listing 7.6 kurzoperatoren1.apsx

using System;

class ConsoleApp{static void Main(){int i = 0;

do{i = i + 1;Console.Write ("i ist gleich ");Console.WriteLine(i.ToString());} while(i<10);

Console.ReadLine();}}

C# bietet eine wesentlich bequemere Möglichkeit, eine numerische Variable zuinkrementieren. Jeder Entwickler, dem das Handgelenk schmerzt, wird sich freuen,ein paar Zeichen weniger tippen zu müssen. Folgender Aufruf vereinfacht dieInkrementation:

Page 109: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

7 Operatoren _________________________________________________________109

Listing 7.7 kurzoperatoren2.cs

using System;

class ConsoleApp{static void Main(){int i = 0;

do{i++;Console.WriteLine("i ist gleich ");Console.WriteLine(i.ToString());} while(i<10);

Console.ReadLine();}}

Das Ergebnis ist identisch. Natürlich kann man analog auch dekrementieren, indemman das „++“ durch „– –“ ersetzt; eigentlich ganz logisch, oder?

Listing 7.8 kurzoperatoren3.cs

using System;

class ConsoleApp{static void Main(){int i = 10;

do{Console.Write ("i ist gleich ");Console.WriteLine(i.ToString());i--;} while(i<10);

Console.ReadLine();}}

++ Operator

– – Operator

Page 110: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

110 _____________________________________________ 7.3 Zuweisungsoperatoren

Tabelle 7.2 Die mathematischen Kurz-Operatoren in der Übersicht

Operator Beschreibung

++ Inkrementiert die zuvor notierte Variable

– – Dekrementiert die zuvor notierte Variable

7.3 Zuweisungsoperatoren

Neben den beiden beschriebenen Kurz-Operatoren kennt C# eine weitereMöglichkeit, Ihnen Tipparbeit abzunehmen und so wertvolle Zeit zu sparen:Zuweisungsoperatoren. Bei dieser Art von Operatoren wird parallel eineRechenoperation und eine erneute Zuweisung durchgeführt. Das folgende Beispielzeigt die Verwendung im Vergleich zu regulären Operatoren.

Listing 7.9 zuweisungsoperatoren1.cs

using System;

class ConsoleApp{static void Main(){int i1 = 3;int i2 = 3;

i1 = i1 + 4;Console.WriteLine("i1 = i1 + 4 ergibt " +i1.ToString());

i2 += 4;Console.WriteLine("i2 += 4 ergibt " +i2.ToString());

Console.ReadLine();}}

Diese Art von Operator existiert für alle vier Grundrechenarten sowie dieBerechnung des Restbetrages, Modulo. Das Vorgehen ist dabei jeweils identisch.Der Wert der links vor dem Operator notierten Variable wird mit dem rechts davonnotierten Wert berechnet und dann wieder der ersten Variable zugewiesen. EineZusammenstellung der weiteren Zuweisungsoperatoren finden Sie im folgendenBeispiel.

+=

Page 111: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

7 Operatoren _________________________________________________________111

Listing 7.10 zuweisungsoperatoren2.cs

using System;

class ConsoleApp{static void Main(){int i1 = 3;int i2 = 6;int i3 = 9;int i4 = 12;

i1 -= 2;Console.WriteLine("i1 -= 2 ergibt " +i1.ToString());Console.WriteLine("");

i2 *= 3;Console.WriteLine("i2 *= 3 ergibt " +i2.ToString());Console.WriteLine("");

i3 /= 3;Console.WriteLine("i3 /= 3 ergibt " +i3.ToString());Console.WriteLine("");

i4 %= 5;Console.WriteLine("i4 %= 5 ergibt " +i4.ToString());Console.WriteLine("");

Console.ReadLine();}}

Natürlich können Sie rechts statt einem Wert auch eine zweite Variable oder gar dasErgebnis einer weiteren Berechnung oder Funktion notieren. Lediglich links vomOperator muss immer eine Variable, ein Indexer oder Ähnliches notiert werden, umdas Ergebnis der Operation aufzunehmen. Alles andere weist der C#-Compiler miteiner Fehlermeldung zurück. So auch das folgende Beispiel:

Listing 7.11 zuweisungsoperator3.cs

3 += 3;

–=

Page 112: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

112 _____________________ 7.4 Noch mehr Mathematik mit der Klasse System.Math

Die Fehlermeldung lautet in diesem Fall ganz richtig: „Compilerfehlermeldung:CS0131: Die linke Seite einer Zuweisung muss eine Variable, eine Eigenschaft oderein Indexer sein.“

Tabelle 7.3 Die mathematischen Zuweisungsoperatoren in der Übersicht

Operator Beschreibung

+= Addiert die linke Variable mit dem rechten Wert und weist das Ergebnisder Variablen zu.

–= Subtrahiert den rechten Wert von der linken Variable und weist dasErgebnis der Variablen zu.

*= Multipliziert die linke Variable mit dem rechten Wert und weist dasErgebnis der Variablen zu.

/= Dividiert die linke Variable durch den rechten Wert und weist das Ergebnisder Variablen zu.

%= Dividiert die linke Variable durch den rechten Wert und weist denRestbetrag der Variablen zu.

7.4 Noch mehr Mathematik mit der Klasse System.Math

Die im Namespace System verankerte Klasse Math bietet zwar keine Operatoren,kann dafür aber mit vielen wichtigen mathematischen Methoden aufwarten und istdaher in diesem Kontext durchaus erwähnenswert.In anderen Umgebungen wären die Methoden dieser Klasse vermutlich alsFunktionen in der Sprache selbst verankert. Nicht so bei C# respektive .NET. Hiersind Funktionalität und Sprache streng getrennt. Sie können daher die hierbeschriebene Klasse auch ohne weiteres in Visual Basic.NET, JScript 7 oder auchjeder anderen .NET-Sprache verwenden, die uns die Hersteller bescheren werden.Alle Methoden der Klasse sind statisch implementiert. Sie müssen die Klasse dahernicht instanzzieren, sondern können die Methode direkt aufrufen. Viele derMethoden sind überladen und passen sich so flexibel Ihren Bedürfnissen und denübergebenen Daten an. Die folgende Tabelle enthält eine Übersicht derunterstützten Methoden.

Tabelle 7.4 Die Methoden der Klasse Math in der Übersicht

Methode Beschreibung

Abs Berechnet den absoluten Betrag eines übergebenen Wertes

Acos Berechnet den Arcuscosinus eines übergebenen Cosinus-Wertes

Asis Berechnet den Arcussinus eines übergebenen Sinus-Wertes

Atan Berechnet den Arcustangens eines übergebenen Tangens-Wertes

Page 113: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

7 Operatoren _________________________________________________________113

Methode Beschreibung

Atan2 Berechnet den Arcustangens des Quotienten zweier übergebener Werte(x, y)

Ceiling Rundet den übergebenen Wert zur nächsthöheren oder gleichenGanzzahl auf

Cos Berechnet den Cosinus

Cosh Berechnet den hyperbolischen Cosinus

Exp Berechnet e hoch den übergebenen Wert

Floor Das Gegenstück zu Ceiling rundet den übergebenen Wert zurnächstkleineren oder gleichen Ganzzahl ab.

Log Berechnet den Logarithmus eines übergebenen Wertes

Log10 Berechnet den Logarithmus der Basis 10 eines übergebenen Wertes

Max Gibt den größeren zweier übergebener Werte zurück

Min Gibt den kleineneren zweier übergebener Werte zurück

Pow Potenziert einen übergebenen Wert mit einem zweiten, x hoch y

Round Rundet einen Wert mathematisch zur nächsten Ganzzahl auf oder ab.Über einen optionalen Parameter kann die Anzahl der zu berechnendenNachkommastellen angegeben werden.

Sign Liefert einen Hinweis auf das Vorzeichen eines übergebenen Wertes, 1für positive Werte und –1 für negative

Sin Berechnet den Sinus

Sinh Berechnet den hyperbolischen Sinus

Sqrt Berechnet die Wurzel eines übergebenen Wertes

Tan Berechnet den Tangens

Tanh Berechnet den hyperbolischen Tangens

Das folgende Beispiel wendet eine kleine Auswahl der angebotenen Methoden insimplen Beispielen an. In der Regel sind die Methoden und deren Parameter selbsterklärend.

Listing 7.12 math1.csusing System;

class ConsoleApp{static void Main(){Console.WriteLine("Was ist kleiner, 6 oder 5? Na klar: ");Console.WriteLine(Math.Min(6, 5).ToString());Console.WriteLine("");

Console.WriteLine("Und wie ist die gerundete Zahl von 5,577? ");Console.WriteLine(Math.Round(5.577).ToString());

Page 114: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

114 _____________________ 7.4 Noch mehr Mathematik mit der Klasse System.Math

Console.WriteLine("");

Console.WriteLine("Ich liebe Wurzelberechung!");Console.WriteLine("Wie lautet die Wurzel von 169? ");Console.WriteLine(Math.Sqrt(169).ToString());Console.WriteLine("");

Console.WriteLine("Und wie habe ich das ausgerechnet?");Console.WriteLine("Über den Umweg 13 hoch 2: ");Console.WriteLine(Math.Pow(13, 2).ToString());Console.WriteLine("");

Console.ReadLine();}}Zusätzlich zu den beschriebenen Rechenfunktionen enthält die Klasse auch nochzwei oft verwendete mathematische Werte als Eigenschaften. Es handelt sich umden Exponenten e und die Zahl Pi. Beide Werte können über die gleichnamigenEigenschaften abgefragt werden. Achtung: Notieren Sie die Namen unbedingtkomplett in Großbuchstaben, sonst kann C# nichts damit anfangen.

Listing 7.13 math2.cs

using System;

class ConsoleApp{static void Main(){Console.WriteLine("Wie lautet der Exponent e? ");Console.WriteLine(Math.E.ToString());Console.WriteLine("");

Console.WriteLine("Und wie sieht es mit Pi aus? ");Console.WriteLine(Math.PI.ToString());Console.WriteLine("");

Console.ReadLine();}}

Page 115: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

7 Operatoren _________________________________________________________115

7.5 Logische Operatoren

Tief im Inneren kennt Ihr PC nur zwei Zustände: Strom an oder Strom aus. Auf dieProgrammierung übertragen, handelt es sich um einen logischen, genanntbooleschen, Zustand: ja oder nein. Logische Operatoren basieren auf dieserkleinstmöglichen Information. Die Werte hierfür sind „true“ und „false“.

7.5.1 Vergleichsoperatoren

Vergleichsoperatoren dienen dem Vergleich zweier links beziehungsweise rechtsvom Operator notierter Werte und liefern das Ergebnis des Vergleichs als logischen(booleschen) Wert zurück. Die folgende Tabelle enthält eine Übersicht der zurVerfügung stehenden Vergleichsoperatoren. Das anschließende Beispiel zeigt dieVerwendung des Kleiner-gleich-Vergleiches.

Tabelle 7.5 Die Vergleichsoperatoren in der Übersicht

Operator Beschreibung

x == y x gleich y?

x != y x ungleich y?

x < y x kleiner als y?

x > y x größer als y?

x <= y x kleiner oder gleich y?

x >= y x größer oder gleich y?

Listing 7.14 vergleich1.cs

using System;

class ConsoleApp{static void Main(){Console.WriteLine("Ist 2 kleiner-gleich 3? ");

if(2<=3)Console.WriteLine("Na klar!");elseConsole.WriteLine("Auf keinen Fall!");

Console.WriteLine("Und wie sieht es mit 5 und 1 aus? ");

if(5<=1)Console.WriteLine("Na klar!");else

<=

Page 116: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

116 ______________________________________________ 7.5 Logische Operatoren

Console.WriteLine("Auf keinen Fall!");

Console.ReadLine();}}

Ob und – wenn ja – wie die Operatoren verwendet werden können, hängt ganz vonden verwendeten Objekttypen ab. Zwei Zahlen werden selbstverständlichmathematisch verglichen. Bei Zeichenketten wird der jeweilige Inhalt verglichen.Bei anderen Verweisobjekten werden die Operatoren der zu Grunde liegendenKlasse aufgerufen. Diese vergleichen allerdings nicht den Inhalt der Objekte,sondern den Verweis. Zwei Objekte müssen daher auf die gleiche Instanz einerKlasse verweisen, damit sie übereinstimmen. In jedem Fall sind beide Objekte nichtidentisch, selbst wenn der jeweilige Inhalt identisch sein sollte. Im zweiten Teil desKapitels zur objektorientierten Programmierung wird eine Möglichkeit vorgestellt,eigene Operatoren zu implementieren. Für diese gilt die Einschränkung unterUmständen nicht.

7.5.2 Verknüpfungsoperatoren

Operationen lassen sich auch logisch verknüpfen. C# stellt hierzu ein logisches„und“ sowie ein logisches „oder“ zur Verfügung. Beide arbeiten ausschließlich aufBasis von logischen Operationen, also booleschen Werten. Die Tabelle zeigt beideOperatoren in der Übersicht. Die Listings zeigen verschiedene Verknüpfungen imBeispiel.

Tabelle 7.6 Die Verknüpfungsoperatoren in der Übersicht

Operator Beschreibung

&& Logisches „und“ („and“) der beiden Operanden

|| Logisches „oder“ („or“) der beiden Operanden

Listing 7.15 verknüpfungsoperatoren1.cs

using System;

class ConsoleApp{static void Main(){bool b1 = true;bool b2 = false;

if(b1 && b2)

&&

Page 117: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

7 Operatoren _________________________________________________________117

Console.WriteLine("b1 und b2 sind beide wahr");elseConsole.WriteLine("b1 und/oder b2 sind nicht wahr");

Console.ReadLine();}}

Da b2 nicht wahr (true) ist, wird der else-Zweig der if-Abfrage durchgeführt undein negativer Text ausgegeben. Anders sieht es im folgenden Beispiel für denVerknüpfungsoperator „oder“ aus, denn hier muss nur eine der beiden Variablenwahr sein. Entsprechend trifft die if-Abfrage zu und ein positiver Text wirdausgegeben.

Listing 7.16 verknüpfungsoperatoren2.cs

using System;

class ConsoleApp{static void Main(){bool b1 = true;bool b2 = false;

if(b1 || b2)Console.WriteLine("b1 oder b2 sind wahr");elseConsole.WriteLine("b1 und b2 sind nicht wahr");

Console.ReadLine();}}

Die beiden Verknüpfungsoperatoren weisen im Gegensatz zu den weiter untenbeschriebenen bitweisen Operatoren eine gewisse „Intelligenz“ auf. Ist beimlogischen „und“ der erste Teil bereits Falsch, wird der nachfolgende Operand nichtmehr ausgewertet, da die Verknüpfung ohnehin falsch ergeben würde. Ähnlichverhält es sich beim logischen „oder“. Hier wird der zweite Operand nur dannausgewertet, wenn der erste falsch ist, da die Verknüpfung in anderen immer wahrsein muss.

||

Page 118: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

118 ______________________________________________ 7.5 Logische Operatoren

7.5.3 Negationsoperator

Der Negationsoperator negiert einen logischen Wert. Aus ja wird also nein undumgekehrt. Dieser Operator kommt implizit bereits beim ungleich-Vergleich weiteroben zum Einsatz und wird mit dem Ausrufezeichen „!“ notiert.

Listing 7.17 negation1.cs

using System;

class ConsoleApp{static void Main(){if(!true)Console.WriteLine("Ja!");elseConsole.WriteLine("Nein!");

Console.ReadLine();}}

7.5.4 Bitweise (binäre) Operatoren

Bitweise Operatoren erlauben den Zugriff sowie die Manipulation von Werten aufBit-Ebene. Es können dabei sowohl numerische als auch logische Datentypenangegeben werden. Es existieren fünf verschiedene Operatoren, die in derfolgenden Tabelle aufgelistet werden.

Tabelle 7.7 Bitweise Operatoren in der Übersicht

Operator Beschreibung

& Bitweise „und“-Verknüpfung der beiden Operanden

| Bitweise „oder“-Verknüpfung der beiden Operanden

^ Bitweise exklusive „oder“-Verknüpfung (XOR) der beiden Operanden

>> Verschieben aller Bits des Operanden um die angegebene Anzahl nachrechts

<< Verschieben aller Bits des Operanden um die angegebene Anzahl nachlinks

Die ersten beiden Operanden sind schnell erklärt, denn diese sind den weiter obenbereits beschriebenen logischen Verknüpfungsoperatoren sehr ähnlich. Der einzigeUnterschied: beide Operatoren arbeiten auf Bit-Ebene, sofern mit numerischen

!

Page 119: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

7 Operatoren _________________________________________________________119

Werte operiert wird. Bei logischen (booleschen) Werten hingegen, stimmt dasErgebnis mit den logischen Verknüpfungsoperatoren überein. Allerdings wird dieOperation hierbei in jedem Fall durchgeführt, unabhängig vom Wert des erstenOperanden.Die bitweise oder binäre Verknüpfung zweier binärer Operanden liefert einendritten binären Wert zurück, bei dem diejenigen Bits gesetzt werden, die bei beidenOperanden gesetzt sind. Das folgende Beispiel erläutert das Vorgehen:

0 1 0 1 1 0 0 1 1& 0 0 0 1 0 1 1 0 1= 0 0 0 1 0 0 0 0 1

Im Dezimalsystem entsprechen diese binären Werte 179 und 45. Das Ergebnis ist33. Das folgende Beispiel zeigt die Verknüpfung im Einsatz.

Listing 7.18 bitweise1.apsx

using System;

class ConsoleApp{static void Main(){int n1 = 179;int n2 = 45;

Console.WriteLine("179 & 45 ergibt ");Console.WriteLine((n1 & n2).ToString());

Console.ReadLine();}}

Möchte man feststellen, ob ein bestimmtes Bit eines Wertes gesetzt ist, dann mussman nur die beiden Werte miteinander bitweise mit dem „und“-Operatorverknüpfen. Falls das Bit gesetzt ist, muss das Ergebnis dem Vergleich entsprechen.Möchte man beispielsweise ermitteln, ob das erste Bit gesetzt ist, reicht eineVerknüpfung mit der Dezimalzahl 1. Liefert diese Verknüpfung erneut denDezimalwert 1 zurück, dann ist das erste Bit gesetzt, ansonsten nicht.

Listing 7.19 bitweise2.cs

using System;

class ConsoleApp{

Binäres Und

Page 120: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

120 ______________________________________________ 7.5 Logische Operatoren

static void Main(){int n1 = 15; // = binär 1111

Console.WriteLine("Das erste Bit des Dezimalwertes ");Console.WriteLine(n1.ToString() + " ist ");

if((n1 & 1) == 1)Console.WriteLine("gesetzt!");elseConsole.WriteLine("nicht gesetzt!");

Console.ReadLine();}}

Analog zu der bitweisen „und“-Verknüpfung arbeitet die „oder“-Verknüpfung.Allerdings wird hier ein Wert zurückgeliefert, bei dem alle Bits gesetzt sind, die beimindestens einem der beiden Operanden (oder beiden!) gesetzt sind. Dasvorangegangene Beispiel zeigt sich wie folgt:

0 1 0 1 1 0 0 1 1| 0 0 0 1 0 1 1 0 1= 0 1 0 1 1 1 1 1 1

Das dezimale Ergebnis der Operation ist in diesem Fall 191.

Listing 7.20 bitweise2.cs

using System;

class ConsoleApp{static void Main(){int n1 = 179;int n2 = 45;

Console.WriteLine("179 | 45 ergibt ");Console.WriteLine((n1 | n2).ToString());

Console.ReadLine();}}

Die exklusive „oder“-Verknüpfung unterscheidet sich ganz entscheidend von derregulären (nicht exklusiven) „oder“-Verknüpfung. Diese liefert einen Wert zurück,bei dem alle Bits gesetzt sind, die bei einem der beiden Operanden und nur bei

Binäres Oder

Page 121: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

7 Operatoren _________________________________________________________121

einem gesetzt sind. Ist ein Bit bei beiden Operanden gesetzt, wird dieses Bit imErgebnis nicht gesetzt. Auch dieser Operator lässt sich mit booleschen Wertenverwenden. Die beiden folgenden Beispiele zeigen daher sehr deutlich denUnterschied zwischen den beiden „oder“-Verknüpfungen.

Listing 7.21 bitweise4.cs

using System;

class ConsoleApp{static void Main(){bool b1 = true;bool b2 = true;

if(b1 | b2)Console.WriteLine("b1 | b2 liefert true");elseConsole.WriteLine("b1 | b2 liefert false");

Console.ReadLine();}}

Die Operation liefert wahr zurück, denn mindestens einer der beiden Operanden(oder wie in diesem Fall beide) sind wahr. Ganz anders sieht es im zweiten Beispielaus, das falsch zurückliefert, da mehr als einer der beiden Operanden wahr ist.

Listing 7.22 bitweise5.cs

using System;

class ConsoleApp{static void Main(){bool b1 = true;bool b2 = true;

if(b1 ^ b2)Console.WriteLine("b1 ^ b2 liefert true");elseConsole.WriteLine("b1 ^ b2 liefert false");

Console.ReadLine();}}

Exklusives Oder

Page 122: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

122 ______________________________________________ 7.5 Logische Operatoren

Zu guter Letzt bietet C# noch zwei weitere Verknüpfungsoperatoren an. DasVerschieben (genannt „Shiften“) aller Bits eines Wertes um einen angegebenenWert nach rechts oder links. Die Operatoren werden als „>>“ beziehungsweise„<<“ notiert. Anders als man annehmen mag, rotieren die Bits nicht. Bei jederOperation fällt daher auf der Seite, in die man wechselt, ein Bit heraus. Auf dergegenüberliegenden Seite wird ein Bit nachgeschoben. Dies Bit orientiert sich amVorzeichen des Wertes. Ist dieser positiv, wird eine 0 nachgeschoben, ansonsteneine 1.Die bitweise Verschiebung lässt sich sehr gut mit einem oft verwendeten Beispielveranschaulichen. Dabei werden alle Bits eines dezimalern Wertes (int) in einerSchleife jeweils um ein Bit nach rechts verschoben. Dann wird geprüft, ob das ersteBit von rechts gesetzt ist. Auf diese Weise lässt sich eine Zeichenkettezusammensetzen, die den korrespondierenden Binärwert enthält.

Listing 7.23 bitweise6.cs

using System;

class ConsoleApp{static void Main(){const int ndecstart = 24540545;

int ndecvalue = ndecstart;string sbinvalue = "";

for(int i=1; i<=32; i++){if((ndecvalue & 1) == 1)sbinvalue = "1" + sbinvalue;elsesbinvalue = "0" + sbinvalue;ndecvalue = ndecvalue >> 1;}

Console.WriteLine("Der Dezimalwert ");Console.WriteLine(ndecstart.ToString());Console.WriteLine(" entspricht dem Binärwert ");Console.WriteLine(sbinvalue);

Console.ReadLine();}}

Shiften mit<< und >>

Page 123: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

7 Operatoren _________________________________________________________123

Das Beispiel liefert für den angegebenen dezimalen Wert den korrespondierendenBinärwert. Die Ausgabe sieht wie folgt aus:

Der Dezimalwert 24540545 entspricht dem Binärwert00000001011101100111010110000001

7.6 Typenoperatoren

7.6.1 typeof

Der Operator typeof liefert eine Instanz der Klasse System.Type für eineübergebene Klasse. Die Klasse bietet unter dem Stichwort „Reflections“ Zugriff aufdie Typeninformationen eines Objektes, also dessen Methoden, Eigenschaften,Ereignisse, und so weiter. Dieser Zugriff ist äußerst detailliert.Das folgende Beispiel ist ein wenig komplex und greift bereits dem weiter untenfolgenden Kapitel „Reflections“ voraus. Die prinzipiellen Möglichkeiten der KlasseSystem.Type werden aber bereits beim Überfliegen des Beispiels deutlich.

Listing 7.24 typeof1.cs

using System;using System.Reflection;

class ConsoleApp{static void Main(){Type t = typeof(string);

Console.WriteLine("<h2>Methoden der Klasse string</h2>");

MethodInfo[] methods = t.GetMethods();foreach (MethodInfo method in methods){Console.WriteLine(method.ToString() + "");}

Console.WriteLine("<h2>Eigenschaften der Klasse string</h2>");

PropertyInfo[] properties = t.GetProperties();foreach (PropertyInfo property in properties){Console.WriteLine(property.ToString() + "");

System.Type

Page 124: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

124 _________________________________________________ 7.6 Typenoperatoren

}

Console.ReadLine();}}

Was passiert hier? Zuerst wird eine neue Instanz der Klasse System.Type durchAufruf des typeof-Operators erzeugt. In diesem Fall wird der Datentyp stringübergeben. Die Instanz der System.Type-Klasse bezieht sich also auf diesenDatentyp. Über die Methode GetMethods wird nun ein Array aller Methoden derKlasse erzeugt. Anschließend werden diese ausgegeben. Auf die gleiche Art werdennun alle Eigenschaften der Klasse aufgelistet. Wenn man diese Zeilen vor Augenhat, ist es eigentlich gar nicht mehr so schwierig. Selbstverständlich funktioniert dasBeispiel auch und liefert die folgenden (gekürzten) Ausgaben.

Methoden der Klasse stringSystem.String ToString(System.IFormatProvider)System.TypeCode GetTypeCode()System.Object Clone()Int32 CompareTo(System.Object)Int32 GetHashCode()Boolean Equals(System.Object)System.String ToString()System.String Join(System.String, System.String[])System.String Join(System.String, System.String[], Int32, Int32)Boolean Equals(System.String)Boolean Equals(System.String, System.String)Boolean op_Equality(System.String, System.String)Boolean op_Inequality(System.String, System.String)Char get_Chars(Int32)Void CopyTo(Int32, Char[], Int32, Int32)Char[] ToCharArray()Char[] ToCharArray(Int32, Int32)Int32 get_Length()System.String[] Split(Char[])System.String[] Split(Char[], Int32)System.String Substring(Int32)System.String Substring(Int32, Int32)System.String Trim(Char[])System.String TrimStart(Char[])System.String TrimEnd(Char[])...

Eigenschaften der Klasse string

Char Chars [Int32]Int32 Length

Page 125: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

7 Operatoren _________________________________________________________125

Falls Sie sich wundern, warum eine Methode mehr als einmal auftaucht, beachtenSie bitte die unterschiedliche(n) Parameter(-anzahl). Es handelt sich in diesenFällen um überladene Methoden.Beachten Sie bitte auch, dass dem Operator typeof nur ein Typ übergeben werdenkann, nicht aber eine Instanz dieses Typs. Möchten Sie den Typ einer bestehendenInstanz erfahren, verwenden Sie einfach die Methode GetType, die von jedemObjekt implementiert wird. Das vorangegangene Beispiel sähe in diesem Fall wiefolgt aus.

Listing 7.25 typeof2.cs

using System;using System.Reflection;

class ConsoleApp{static void Main(){string text = "hallo welt";Type t = text.GetType();

Console.WriteLine("<h2>Methoden der Klasse string</h2>");

MethodInfo[] methods = t.GetMethods();foreach (MethodInfo method in methods){Console.WriteLine(method.ToString() + "");}

Console.WriteLine("<h2>Eigenschaften der Klasse string</h2>");

PropertyInfo[] properties = t.GetProperties();foreach (PropertyInfo property in properties){Console.WriteLine(property.ToString() + "");}

Console.ReadLine();}}

Page 126: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

126 _________________________________________________ 7.6 Typenoperatoren

7.6.2 is

Mit dem is-Operator lässt sich abfragen, ob ein Objekt einem angegebenenDatentyp entspricht beziehungsweise eine bestimmte Schnittstelle implementiert.Im praktischen Einsatz wird gerade letztere Möglichkeit häufig benutzt, wenn manein fremdes Objekt übergeben bekommt und wissen möchte, ob die benötigteSchnittstelle vorhanden ist. Das Beispiel zeigt die Überprüfung.

Listing 7.26 is1.cs

using System;

class ConsoleApp{static string GetString(object obj){if(obj is string){string s = (string) obj;return("Das Objekt enthält den String \"" +s + "\"");

}elsereturn("Objekt ist kein string");

}

static void Main(){string s = "hallo welt";int n = 123;

Console.WriteLine(GetString(s));Console.WriteLine(GetString(n));

Console.ReadLine();}}

Im Beispiel wird der Methode GetString ein beliebiges Objekt übergeben. DieMethode prüft, ob das Objekt vom Typ string ist beziehungsweise von diesemDatentyp abgeleitet wurde. Ist dies der Fall, erfolgt eine Konvertierung in den Typstring und der Inhalt der Zeichenkette wird zurückgegeben. Ist dies nicht der Fall,wird ein negativer Text zurückgegeben. Die Ausgabe des Beispiels fällterwartungsgemäß wie folgt aus.

Das Objekt enthält den String "hallo welt"Objekt ist kein string

Datentypüberprüfen

Page 127: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

7 Operatoren _________________________________________________________127

7.6.3 as

Der Operator as ist dem vorangegangenen is sehr ähnlich. Allerdings führt as eineexplizite Konvertierung in den angegebenen Datentyp durch und liefert daskonvertierte Objekt zurück. Ist eine Konvertierung nicht möglich, da das Objekt dengewünschten Datentyp nicht unterstützt, gibt der Operator null zurück.Das vorangegangene Beispiel lässt sich mit wenigen Handgriffen auf den as-Operator umstellen; das Ergebnis ist identisch.

Listing 7.27 as1.cs

using System;

class ConsoleApp{public static string GetString(object obj){string s = obj as string;if(s != null)return("Das Objekt enthält den String \"" +s + "\"");

elsereturn("Objekt ist kein string");

}

static void Main(){string s = "hallo welt";int n = 123;

Console.WriteLine(GetString(s));Console.WriteLine(GetString(n));

Console.ReadLine();}}

Datentypkonvertieren

Page 128: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

128 _________________________________________________ 7.6 Typenoperatoren

7.6.4 is versus as

Der is-Operator sollte verwendet werden, wenn man lediglich die Informationbenötigt, ob das Objekt einem bestimmten Datentyp entspricht oder eineSchnittstelle implementiert. Möchte man hingegen auf das entsprechendkonvertierte Objekt anschließend zugreifen, sollte der as-Operator verwendetwerden, da auf diese Weise eine nochmalige Konvertierung wegfällt. In beidenBeispielen lässt sich dieser Vorteil durch den Wegfall der folgenden Zeile deutlicherkennen:

...string s = (string) obj;...

Page 129: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

8Arbeiten mit Zeichenketten

Der Datentyp string

Die Klasse StringBuilder

Reguläre Ausdrücke

Page 130: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

130 ___________________________________________________________________

Inhaltsübersicht Kapitel 8

8 Arbeiten mit Zeichenketten ............................................................................131

8.1 Der Datentyp string ...........................................................................................1318.1.1 Einfache Zuweisungen.......................................................................................1318.1.2 Escape-Zeichen..................................................................................................1328.1.3 Formatierungen..................................................................................................1348.1.4 String-Eigenschaften .........................................................................................1368.1.5 Weitere String-Operationen...............................................................................1388.2 Die Klasse StringBuilder ...................................................................................1488.2.1 StringBuilder-Eigenschaften..............................................................................1498.2.2 StringBuilder-Methoden ....................................................................................1508.3 Reguläre Ausdrücke ..........................................................................................1528.3.1 Der Aufbau von regulären Ausdrücken .............................................................1538.3.2 Die Klasse Regex...............................................................................................1578.3.3 Die Regex-Optionen ..........................................................................................1648.3.4 Erweiterte Parsing-Möglichkeiten .....................................................................166

Page 131: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

___________________________________________________________________ 131

8 Arbeiten mit Zeichenketten

Als moderne Programmiersprache bietet C# beziehungsweise das .NET Frameworkumfangreiche Möglichkeiten zur Anlage und Modifikation von Zeichenketten. Jenachdem, welche Anforderungen an die Verarbeitung gestellt werden, könnenunterschiedliche Objekte verwendet werden.

8.1 Der Datentyp string

Der Datentyp string gehört zu den Standard-Datentypen. Als Einziger dieserStandard-Datentypen handelt es sich beim string um einen Verweistyp und nichtum einen Wertetyp. Aus diesem Umstand erklärt sich die Tatsache, dass ein stringin der Größe nur durch den zur Verfügung stehenden Arbeitsspeicher beschränktist. Der zur Ablage notwendige Speicherplatz wird auf dem Heap alloziert.

8.1.1 Einfache Zuweisungen

Sofern Sie eine Zeichenkette direkt und somit fest („hart“) eingeben, wird diese inAnführungszeichen notiert. Eine einfache string-Zuweisung sieht daher so aus:

string s1 = "Hallo Welt";

Auch Zusammensetzungen sind problemlos möglich. Hier können die bekanntenOperatoren wie + und += verwendet werden:

Listing 8.1 string2.cs

using System;

class ConsoleApp{static void Main(){string s1 = "Hallo Welt";

Zeichenkettenzusammen-setzen

Page 132: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

132 _______________________________________________ 8.1 Der Datentyp string

Console.WriteLine(s1);

Console.ReadLine();}}

Wie schaut die Ausgabe dieses Beispiels aus? Natürlich so:

Hallo Welt, was ist hier los?

8.1.2 Escape-Zeichen

Bestimmte Sonderzeichen wie Anführungszeichen, Backslash und so weiter habenin C# eine bestimmte Sonderbedeutung. Sie tragen die Namen Escape-Zeichen undkönnen Zeichenketten nicht direkt zugewiesen werden. Es ist eine Maskierungdieser Zeichen mit Hilfe des Backslash notwendig. Um also einen Text mitAnführungszeichen einem string zuzuweisen, verwenden Sie die folgendeNotierung:

Listing 8.2 escape1.cs

using System;

class ConsoleApp{static void Main(){string s1 = "Dieser Text steht in \"Anführungszeichen\"";

Console.WriteLine(s1);

Console.ReadLine();}}

Die Ausgabe schaut so aus:

Dieser Text steht in "Anführungszeichen"

Überlegen Sie nun bitte einmal, welche Zeichenketten typischerweiseSonderzeichen wie den Backslash enthalten. Richtig, dies sind beispielsweisejegliche Art von Verzeichnis- und Dateipfaden. Diese müssen daher immer mitdoppelten Backslashs angegeben werden:

Page 133: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

8 Arbeiten mit Zeichenketten _____________________________________________133

Listing 8.3 escape2.cs

using System;

class ConsoleApp{static void Main(){string filename = "c:\\windows\\test.xml";

Console.WriteLine(filename);

Console.ReadLine();}}

Gerade bei Pfaden ist dies aber sehr umständlich, da gegebenenfalls vor derSpeicherung Ersetzungen vorgenommen werden müssen. Sie können dieVerwendung von Escape-Zeichen daher für eine Zeichenkette abschalten. Hierzuverwenden Sie einfach das @-Zeichen vor der Angabe der Zeichenkette. Undschwups können Sie auf die Maskierung verzichten:

string filename = @"c:\windows\test.xml";

Response.Write(filename);

Falls Sie sich jetzt fragen, warum überhaupt Escape-Zeichen verwendet werden unddiese nicht grundsätzlich ausgeschaltet sind, möchte ich Ihnen einige weiterevorstellen. Die Angabe dieser Zeichen erleichtert Ihnen beispielsweise das Einfügeneines Zeilenumbruches. Auch beliebige andere Zeichen können Sie ganz einfach inForm eines hexadezimalen Wertes angeben. Die Tabelle enthält eine Übersicht dergängigsten Escape-Zeichen.

Tabelle 8.1 Escape-Zeichen in der Übersicht

Escape-Zeichen Beschreibung

\’ Einfaches Anführungszeichen

\“ Doppeltes Anführungszeichen

\\ Backslash

\0 Null

\a Löst einen Alarm (Systembeep) aus

\b Backspace

\f Zeilenvorschub (Form feed)

\n Zeilenumbruch (New line)

\r Wagenrücklauf (Carriage return)

Das Zeichen @

Page 134: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

134 _______________________________________________ 8.1 Der Datentyp string

Escape-Zeichen Beschreibung

\t Horizontaler Tabulator

\v Vertikaler Tabulator

\xxxx Beliebiges Zeichen in Form eines hexadezimalen Wertes

8.1.3 Formatierungen

Sie können die statische Methode Format der string-Klasse verwenden, um einenstring aus verschiedenen Werten mit einer bestimmten Formatierung zu erzeugen.Der Format-Methode wird zunächst eine Zeichenkette mit Platzhaltern in der Form{0}, {1}, etc. übergeben. Als weitere Parameter folgen die Werte, die für diePlatzhalter eingesetzt werden sollen. Die Ausgabe eines numerischen Wertes kanndaher sehr einfach wie folgt aussehen:

Listing 8.4 format1.cs

using System;

class ConsoleApp{static void Main(){int n = 12345;

string s = string.Format("Meine Zahl ist {0}.", n);

Console.WriteLine(s);

Console.ReadLine();}}

Die Ausgabe zeigt durch den Punkt nach der Zahl deutlich, dass der Platzhalterersetzt wurde:

Meine Zahl ist 12345.

Neben einfachen Ersetzungen von Platzhaltern lassen sich die Werte auch nochweitergehend manipulieren. Der folgende Aufruf formatiert beispielsweise dieübergebene Zahl beispielsweise als Währung. Es werden dabei die lokaleingestellten Länderinformationen zu Grunde gelegt (bei mir derzeit: Deutsch =Währung DM).

Ausgabe alsWährung

Page 135: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

8 Arbeiten mit Zeichenketten _____________________________________________135

Listing 8.5 format2.cs

using System;

class ConsoleApp{static void Main(){int n = 12345;

string s = string.Format("Währungsformatierung: {0:C}", n);

Console.WriteLine(s);

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Währungsformatierung: 12.345,00 DM

Nach der fortlaufenden Nummer des Platzhalters und einem Doppelpunkt wird diegewünschte Formatierungsart angegeben. Neben der Währungsformatierungenstehen weitere Möglichkeiten zur Verfügung. Die Tabelle zeigt eine Übersicht.

Tabelle 8.2 Die Formatierungszeichen in der Übersicht

Format-Zeichen Beschreibung

Cn Formatiert den Wert als Währung entsprechend Landeseinstellungen,optional mit n Nachkommastellen.

Dn Formatiert den Wert als Dezimalzahl, optional mit n Nachkommastellen.

En Formatiert den Wert als Exponential, optional mit n Nachkommastellen.

Fn Formatiert den Wert als Gleitkommazahl, optional mit nNachkommastellen.

Nn Formatiert den Wert numerisch, optional mit n Nachkommastellen.

P Formatiert den Wert als Prozentwert, optional mit n Nachkommastellen.

R Stellt sicher, dass ein zum string konvertierter numerischer Wert wiederkorrekt zurück konvertiert werden kann (Round-trip).

Xn Formatiert den Wert als Hexadezimalzahl, optional mit n Stellen.

Page 136: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

136 _______________________________________________ 8.1 Der Datentyp string

8.1.4 String-Eigenschaften

Die Klasse string kennt drei Eigenschaften, die bei der Bearbeitung vonZeichenketten nützlich sein können.

Empty (statisch)

Die Eigenschaft Empty liefert einen leeren string zurück und entspricht somit "".Sie können die Eigenschaft verwenden, um eine leere Zeichenkette zuzuweisen undso beispielsweise einen string zu initialisieren. Beachten Sie, dass es sich um einestatische Methode handelt und diese daher nicht vom Objekt, sondern vomDatentyp her aufgerufen werden muss.Die folgenden beiden Aufrufe sind identisch:

Listing 8.6 empty1.cs

string s1 = string.Empty;

string s2 = "";

Chars/ [ ]

Diese Eigenschaft liefert ein Array mit den einzelnen Zeichen der Zeichenkette.Unter C# steht diese Eigenschaft nicht unter diesem Namen zur Verfügung, dafüraber als Indexer des string-Objektes.Im folgenden Beispiel wird der Indexer verwendet, um alle Zeichen derZeichenkette einzeln auszugeben. Es wird ein neuer string instanziiert undanschließend mit einer Schleife Zeichen für Zeichen durchlaufen. Der Indexer(gekennzeichnet durch die eckigen Klammern []) liefert das jeweilige Zeichen.

Listing 8.7 chars1.cs

using System;

class ConsoleApp{static void Main(){string s1 = "Hallo Welt";

for(int i = 0; i<s1.Length; i++){string s2 = string.Format("Zeichen {0:D2} = {1}", i+1, s1[i]);

Page 137: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

8 Arbeiten mit Zeichenketten _____________________________________________137

Console.WriteLine(s2);}

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Zeichen 01 = HZeichen 02 = aZeichen 03 = lZeichen 04 = lZeichen 05 = oZeichen 06 =Zeichen 07 = WZeichen 08 = eZeichen 09 = lZeichen 10 = t

Length

Diese Eigenschaft wurde bereits im vorangegangenen Beispiel verwendet; sie lieferteinen int-Wert mit der Länge der Zeichenkette zurück.

Listing 8.8 length1.cs

using System;

class ConsoleApp{static void Main(){string s1 = "Hallo Welt";

string s2 = string.Format("\"{0}\" ist {1} Zeichen lang.",s1, s1.Length);

Console.WriteLine(s2);

Console.ReadLine();}}

Page 138: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

138 _______________________________________________ 8.1 Der Datentyp string

Ausgabe im Konsolenfenster:

"Hallo Welt" ist 10 Zeichen lang.

8.1.5 Weitere String-Operationen

Neben Format enthält die Klasse string eine ganze Reihe weiterer statischer unddynamischer Methoden zur Bearbeitung von Zeichenketten. Die Tabelle fasst diewichtigsten Methoden zusammen. Mit * gekennzeichnete Methoden sind statischund müssen daher über den Datentyp, nicht aber über eine Instanz aufgerufenwerden.Statischer Aufruf:

string.Methode(...)

Dynamischer Aufruf (über eine Instanz):

string s = "xyz"s.Methode

Beachten Sie, dass die Instanz-Operationen die aktuelle Instanz der Zeichenkettenicht verändern. Die Methoden liefern daher gegebenenfalls eine neue (undentsprechend modifizierte) Zeichenkette auf Basis der aktuellen Instanz zurück.

Tabelle 8.3 Die Methoden der Klasse string im Überblick

Methode Rückgabewert Beschreibung

Compare* int Vergleicht zwei als Parameter übergebeneZeichenketten und liefert 0 zurück, wenn dieseübereinstimmen. Über einen optionalen dritten,booleschen Parameter kann angegeben werden, obdie Groß-Klein-Schreibung ignoriert werden soll.

Concat* string Verbindet zwei oder mehrere übergebeneZeichenketten.

Copy* string Kopiert die übergebene Zeichenkette und liefert eineneue Zeichenkette mit dem gleichen Inhalt zurück.

Equals* bool Prüft, ob die beiden übergebenen Zeichenkettenidentisch sind.

Format* string Formatiert eine Zeichenkette, Beschreibung sieheweiter oben unter „Formatierungen“.

Intern* string Liefert einen Verweis auf die übergebeneZeichenkette.

Page 139: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

8 Arbeiten mit Zeichenketten _____________________________________________139

Methode Rückgabewert Beschreibung

Join* string Verbindet zwei oder mehrere übergebeneZeichenketten. Ein zusätzlicher erster Parameter gibtdabei an, mit welchem Zeichen die einzelnenZeichenketten separiert sind.

CompareTo int Vergleicht die aktuelle Instanz einer Zeichenkette miteiner zweiten als Parameter übergebenenZeichenkette und liefert 0 zurück, wenn dieseübereinstimmen.

CopyTo string Kopiert die aktuelle Instanz einer Zeichenkette undliefert einen neue Zeichenkette mit dem gleichenInhalt zurück.

EndsWith bool Prüft, ob die Zeichenketten mit dem übergebenenWert endet.

Equals bool Prüft, ob die aktuelle Instanz einer Zeichenkette miteiner zweiten übergebenen Zeichenkette identisch ist.

IndexOf int Gibt den Index des ersten Vorkommens einesZeichens oder einer Zeichenkette in der aktuellenInstanz einer Zeichenkette zurück. Über einenoptionalen zweiten Parameter kann ein gewünschterStartindex angegeben werden.

IndexOfAny int Gibt den Index des ersten Vorkommens einesbeliebigen Zeichens aus dem übergebenen char-Array in der aktuellen Instanz einer Zeichenkettezurück.

Insert string Fügt an einer als Parameter angegebenen Positioneine Zeichenkette in die aktuelle Instanz einerZeichenkette ein.

LastIndexOf int Gibt den Index des letzten Vorkommens einesZeichens oder einer Zeichenkette in der aktuellenInstanz einer Zeichenkette zurück. Über einenoptionalen zweiten Parameter kann ein gewünschterStartindex angegeben werden.

LastIndexOfAny int Gibt den Index des letzten Vorkommens einesbeliebigen Zeichens aus dem übergebenen char-Array in der aktuellen Instanz einer Zeichenkettezurück.

PadLeft string Füllt die aktuelle Zeichenkette mit Leerzeichen odereinem optional übergebenen Zeichen von links bis zurgewünschten Länge auf.

PadRight string Füllt die aktuelle Zeichenkette mit Leerzeichen odereinem optional übergebenen Zeichen von rechts biszur gewünschten Länge auf.

Page 140: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

140 _______________________________________________ 8.1 Der Datentyp string

Methode Rückgabewert Beschreibung

Remove string Entfernt ab der angegebenen Startposition dieangegebene Anzahl an Zeichen aus der aktuellenZeichenkette.

Replace string Ersetzt ein Zeichen oder eine Zeichenkette innerhalbder aktuellen Zeichenkette durch eine andere

Split string[] Separiert die aktuelle Zeichenkette in ein string-Array.Die möglichen Separatoren werden als Parameter inForm eines char-Arrays übergeben.

StartsWiths bool Prüft, ob die Zeichenkette mit dem übergebenen Wertbeginnt.

Substring string Liefert einen Teil der aktuellen Zeichenkette ab derangegebenen Position. Über einen optionalen zweitenParameter kann die Anzahl der auszuschneidendenZeichen angegeben werden. Wird dieser Parameterweggelassen, schneidet die Methode alle Zeichen abder angegebenen Position ab.

ToCharArray char[] Liefert ein char-Array mit den einzelnen Zeichen derZeichenkette.

ToLower string Gibt aktuelle Instanz einer Zeichenkette inKleinbuchstaben zurück.

ToUpper string Gibt aktuelle Instanz einer Zeichenkette inGroßbuchstaben zurück.

Trim string Gibt eine neue Zeichenkette auf Basis der aktuellenInstanz zurück, bei der alle Leerzeichen rechts undlinks entfernt wurden.

TrimEnd string Gibt eine neue Zeichenkette auf Basis der aktuellenInstanz zurück, bei der alle Leerzeichen rechtsentfernt wurden.

TrimStart string Gibt eine neue Zeichenkette auf Basis der aktuellenInstanz zurück, bei der alle Leerzeichen links entferntwurden.

Einige der aufgeführten Methoden haben eine besondere Erwähnung verdient undsollen daher an Hand einiger Beispiele veranschaulicht werden.

EndsWith

EndsWith prüft, ob die aktuelle Zeichenkette mit einem bestimmten Zeichen oderwie im folgenden Beispiel mit einer anderen Zeichenkette aufhört.

Letztes Zeichen

Page 141: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

8 Arbeiten mit Zeichenketten _____________________________________________141

Listing 8.9 endswith1.cs

using System;

class ConsoleApp{static void Main(){string s1 = "Hallo Welt";

if(s1.EndsWith("Welt"))Console.WriteLine("Der String hört mit \"Welt\" auf.");elseConsole.WriteLine("Der String hört nicht mit \"Welt\" auf.");

Console.ReadLine();}}

Ausgabe im Konsolenfenster

Der String hört mit "Welt" auf.

IndexOf

Diese Methode gibt die Position eines Zeichens oder einer Zeichenkette in deraktuellen Zeichenkette zurück. Wird die Zeichenkette nicht gefunden, wird –1zurückgeliefert.

Listing 8.10 indexof1.cs

using System;

class ConsoleApp{static void Main(){string s1 = "Hallo Welt";

Console.WriteLine(s1.IndexOf("Welt"));Console.WriteLine(s1.IndexOf("Universum"));

Console.ReadLine();}}

Enthält

Page 142: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

142 _______________________________________________ 8.1 Der Datentyp string

Ausgabe im Konsolenfenster:

6-1

Insert

Die Methode fügt an der angegebenen Position der Zeichenkette ein Zeichen odereine andere Zeichenkette ein.

Listing 8.11 insert1.cs

using System;

class ConsoleApp{static void Main(){string s1 = "Hallo Welt";

Console.WriteLine(s1.IndexOf("Welt"));Console.WriteLine(s1.IndexOf("Universum"));

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Hallo Welt

PadLeft

Diese Methode formatiert die Zeichenkette auf eine bestimmte Anzahl von Zeichenund füllt diese dazu links mit Leerzeichen beziehungsweise einem optionalübergebenen Zeichen auf.

Listing 8.12 padleft1.cs

using System;

class ConsoleApp{

Page 143: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

8 Arbeiten mit Zeichenketten _____________________________________________143

static void Main(){string s1 = "125,55 Euro";

string s2 = s1.PadLeft(15, '*');

Console.WriteLine(s2);

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

****125,55 Euro

Replace

Die Methode Replace wird immer dann verwendet, wenn eine Zeichenkette durcheine andere ersetzt werden soll. Im folgenden Beispiel werde ich ein weniggrößenwahnsinnig oder oute mich als Anhänger des SETI-Programms.

Listing 8.13 replace1.cs

using System;

class ConsoleApp{static void Main(){string s1 = "Hallo Welt";

string s2 = s1.Replace("Welt", "Universum");

Console.WriteLine(s2);

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Hallo Universum

Ersetzen

Page 144: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

144 _______________________________________________ 8.1 Der Datentyp string

Split

Die Methode Split wird verwendet, um eine Zeichenkette in mehrere andereaufzusplitten. Es kann eine beliebige Anzahl an Separatoren in Form eines char-Arrays angegeben werden. Die Methode liefert ein string-Array mit den separiertenInhalten zurück.Im Beispiel wird ein Satz in die einzelnen Wörter zerlegt. Als Separatoren sind dasLeerzeichen sowie das Komma angegeben. In einer foreach..in-Schleife werden dieeinzelnen Wörter (= Elemente des string-Arrays) zeilenweise ausgegeben.

Listing 8.14 split1.cs

using System;

class ConsoleApp{static void Main(){string s1 = "Hallo Welt, dies ist ein wirklich sinnvoller Satz";

char[] c1 = {' ', ','};

string[] s2 = s1.Split(c1);

foreach(string s3 in s2){Console.WriteLine(s3 + "");}

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

HalloWelt

diesisteinwirklichsinnvollerSatz

Page 145: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

8 Arbeiten mit Zeichenketten _____________________________________________145

Substring

Mit Substring können Sie einen Teil aus einer Zeichenkette herauslösen. ImBeispiel wird die Methode in Verbindung mit IndexOf verwendet. Zunächst wirddabei die Position des Wortes „Welt“ gesucht und anschließend wird diesesausgeschnitten und im Konsolenfenster ausgegeben.

Listing 8.15 substring1.cs

using System;

class ConsoleApp{static void Main(){string s1 = "Hallo Welt";

int n1 = s1.IndexOf("Welt");

string s2 = s1.Substring(n1);

Console.WriteLine(s2);

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Welt

ToCharArray

Mit dieser Methode lässt sich allerlei Unfug anstellen. Sie liefert ein char-Array mitden einzelnen Zeichen der Zeichenkette zurück. Die Weiterverarbeitung wird unsdurch die Methoden der Array-Klasse leicht gemacht.Das folgende Beispiel konvertiert eine Zeichenkette zunächst als Großbuchstaben.Nun wird diese mittels der Methode ToCharArray in ein gleichnamiges kopiert.Die statische Methode Sort der Array-Klasse sorgt nun dafür, dass die Zeichenalphanumerisch sortiert werden. Die nun neu angelegte Zeichenkette fügt alleZeichen wieder zusammen. Das nachfolgende (ähnliche Konstrukt) verwendet dieMethode Reverse der Array-Klasse, um die Zeichenkette umzudrehen.

Page 146: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

146 _______________________________________________ 8.1 Der Datentyp string

Listing 8.16 tochararray1.cs

using System;

class ConsoleApp{static void Main(){string s1 = "Hallo Welt";string s2 = s1.ToUpper();

char[] c1 = s2.ToCharArray();Array.Sort(c1);string s3 = new string(c1);Console.WriteLine(s3 + "");

char[] c2 = s2.ToCharArray();Array.Reverse(c2);string s4 = new string(c2);Console.WriteLine(s4 + "");

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

AEHLLLOTWTLEW OLLAH

ToLower/ ToUpper

Die Methode ToUpper wurde bereits im vorangegangenen Beispiel verwendet. Sieliefert eine Kopie der aktuellen Zeichenkette in Großbuchstaben zurück. Analogverhält sich die Methode ToLower, bei der die Kopie in Kleinbuchstaben angelegtwird.

Listing 8.17 tolowertoupper1.cs

using System;

class ConsoleApp{static void Main(){string s1 = "Hallo Welt";

Klein und groß

Page 147: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

8 Arbeiten mit Zeichenketten _____________________________________________147

string s2 = s1.ToUpper();Console.WriteLine("Größenwahnsinnig: " + s2 + "");

string s3 = s1.ToLower();Console.WriteLine("Kleinkariert: " + s3 + "");

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Größenwahnsinnig: HALLO WELTKleinkariert: hallo welt

Trim (TrimEnd/ TrimStart)

Möchten Sie Leerzeichen oder auch andere Zeichen entfernen, die eineZeichenkette rechts und/oder links begrenzen, verwenden Sie eine der drei Trim-Methoden. Trim selbst kombiniert dabei TrimEnd und TrimStart.Das erste Beispiel zeigt das Entfernen von Leerzeichen; die Ausgabe imKonsolenfenster zeigt deutlich, dass die Zeichenkette tatsächlich um dieseerleichtert wurde.

Listing 8.18 trim1.cs

using System;

class ConsoleApp{static void Main(){string s1 = " Hallo Welt ";

string s2 = s1.Trim();

Console.WriteLine("--->" + s2 + "<---");

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

--->Hallo Welt<---

Page 148: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

148 ___________________________________________ 8.2 Die Klasse StringBuilder

Das folgende, zweite Beispiel zeigt das Entfernen von explizit angegebenenZeichen. Der Trim-Methode wird hierzu als Parameter ein char-Array mit dengewünschten Zeichen übergeben. Die Ausgabe zeigt, dass auf diese Weise das Wort„Hallo“ vollständig entfernt wurde.

Listing 8.19 trim2.cs

using System;

class ConsoleApp{static void Main(){string s1 = " Hallo Welt ";

char[] c1 = {' ', 'H', 'a', 'l', 'o'};

string s2 = s1.Trim(c1);

Console.WriteLine("--->" + s2 + "<---");

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

--->Welt<---

8.2 Die Klasse StringBuilder

Mit der StringBuilder-Klasse bietet das .NET Framework eine zweite effizienteMöglichkeit zur Bearbeitung von Strings an. Im Gegensatz zum Datentyp stringkann der Inhalt der Klasse StringBuilder nachträglich verändert werden. Auchwenn die angebotenen Methoden auf den ersten Blick denen von string gleichen,ergibt sich eine andere Funktionalität, da der Aufruf die aktuelle Instanz manipuliertund keine neue zurückliefert.

Page 149: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

8 Arbeiten mit Zeichenketten _____________________________________________149

8.2.1 StringBuilder-Eigenschaften

Capacity

Über diese Eigenschaft kann die Anzahl der für die Klasse reservierten Zeichen imSpeicher abgefragt beziehungsweise gesetzt werden. Sofern Sie der Klasse einen(neuen) Inhalt zuweisen, wird die Eigenschaft gegebenenfalls automatisch auf dennächsten durch 16 teilbaren Wert aufgerundet. Durch explizites Setzen derEigenschaft können Sie Speicher explizit anfordern.

Listing 8.20 capacity1.cs

using System;using System.Text;

class ConsoleApp{static void Main(){StringBuilder s1 = new StringBuilder("Hallo Welt");

Console.WriteLine(s1.Capacity);

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

16

Chars/ [ ]

Die Eigenschaft liefert ein char-Array mit allen Zeichen der Zeichenkette zurück. InC# steht die Eigenschaft nicht unter diesem Namen, dafür aber als Indexer derKlasse zur Verfügung. Ein Beispiel finden Sie in der Beschreibung dergleichnamigen Eigenschaft der Klasse string weiter oben in diesem Kapitel.

Page 150: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

150 ___________________________________________ 8.2 Die Klasse StringBuilder

Length

Die Eigenschaft Length liefert die aktuelle Länge der Zeichenkette zurück undentspricht somit der gleichnamigen Eigenschaft der Klasse string; ein Beispielfinden Sie in der entsprechenden Beschreibung weiter oben in diesem Kapitel.

MaxCapacity

Diese Eigenschaft gibt den maximal zur Verfügung stehenden Platz für die Klassezurück. Normal: 2147483647.

8.2.2 StringBuilder-Methoden

Die Methoden der StringBuilder-Klasse sind denen des Datentyps string ähnlich.Wie beschrieben wirken sich diese jedoch auf die aktuelle Instanz aus undunterscheiden sich auf diese Weise elementar von der Klasse string. Aus diesemGrund besitzen die Methoden zur Manipulierung keinen Rückgabewert.Die StringBuilder-Klasse kommt auf Grund dieser Möglichkeit immer dann zumEinsatz, wenn eine Zeichenkette ein- oder mehrmals nach der Zuweisungmanipuliert oder mehrere Zeichenketten formatiert zusammengefügt werden sollen.

Tabelle 8.4 Die Methoden der Klasse string im Überblick

Methode Rückgabewert Beschreibung

Append - Fügt die übergebene Zeichenkette beziehungsweiseein char-Array an die Zeichenkette an.

AppendFormat - Fügt die übergebene Zeichenkette beziehungsweiseein char-Array an die Zeichenkette an und verwendetdabei die allgemeinen Formatierungsmöglichkeiten;vergleiche „Formatierungen“ weiter oben.

EnsureCapacity int Prüft, ob die zur Verfügung stehende Kapazitätmindestens dem übergebenen Wert entspricht.

Equals bool Prüft, ob die aktuelle Instanz einer Zeichenkette miteiner zweiten übergebenen Zeichenkette identisch ist.

Insert - Fügt an einer als Parameter angegebenen Positioneine Zeichenkette in die aktuelle Instanz eineranderen Zeichenkette ein.

Page 151: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

8 Arbeiten mit Zeichenketten _____________________________________________151

Methode Rückgabewert Beschreibung

Remove - Entfernt ab der angegebenen Startposition dieangegebene Anzahl an Zeichen aus der aktuellenZeichenkette.

Replace - Ersetzt ein Zeichen oder eine Zeichenkette innerhalbder aktuellen Zeichenkette durch eine andere.

AppendFormat

Mit Hilfe der Methode AppendFormat können Sie einer bestehenden Instanz derStringBuilder-Klasse formatiert Zeichenketten hinzufügen. Die Formatierungs-anweisungen entsprechen den bereits bekannten und weiter oben beschriebenen. Eskönnen daher neben Zeichenketten auch numerische Werte, Währungen und soweiter formatiert angehängt werden.Das folgende Beispiel wurde basiert auf einem bereits weiter oben verwendeten undrealisiert dies mit Hilfe einer Instanz der StringBuilder-Klasse. Eine Zeichenkettewird zunächst in die einzelnen Wörter zerlegt. Anschließend läuft eine for-Schleifedurch das entstandene string-Array und fügt die einzelnen Wörter formatiert derStringBuilder-Instanz hinzu. Die vollständige Zeichenkette wird zu guter Letztausgegeben.

Listing 8.21 appendformat1.cs

using System;using System.Text;

class ConsoleApp{static void Main(){string s1 = "Hallo Welt, dies ist ein wirklich sinnvoller Satz";

char[] c1 = {' ', ','};

string[] s2 = s1.Split(c1);

StringBuilder sb1 = new StringBuilder();

for(int i=0; i<s2.Length; i++){sb1.AppendFormat("Wort {0}: {1}\n", i, s2[i]);}

Page 152: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

152 _______________________________________________ 8.3 Reguläre Ausdrücke

Console.WriteLine(sb1);

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Wort 0: HalloWort 1: WeltWort 2:Wort 3: diesWort 4: istWort 5: einWort 6: wirklichWort 7: sinnvollerWort 8: Satz

8.3 Reguläre Ausdrücke

Reguläre Ausdrücke (englisch: „regular expressions“) sind eine sehr leistungsfähigeIdee zum Durchsuchen und Manipulieren von Zeichenketten. Die regulärenAusdrücke sind eine Beschreibungssprache, die das gewünschte Ergebnisbeschreibt. Es lassen sich auf diese Weise komplexe Konstrukte und Operationenauf Basis des Datentyps string oder der Klasse StringBuilder mit wenigenZeichen umschreiben. Zudem sind reguläre Ausdrücke leichter zu pflegen alsindividuelle Such- und Manipulationskonstrukte. Es bestehen starke Parallelen zuSQL, denn auch hier wird das Ergebnis beschrieben, ohne dass der eigentliche Wegdorthin erwähnt wird. Und genau hier liegen die Vorteile, die reguläre Ausdrückezu einem unverzichtbaren Hilfsmittel für alle Entwickler machen, die mitZeichenketten arbeiten.Die interne Verarbeitung von regulären Ausdrücken unterscheidet sich im .NETFramework auf Wunsch ganz erheblich von alternativen Implementierungen. Inanderen Sprachen werden die Ausdrücke zur Laufzeit interpretiert und umgesetzt.Nicht so bei .NET; hier wird vom Compiler ein Programmteil erzeugt, der dienotwendigen Konstrukte für diesen speziellen Ausdruck implementiert. Auf dieseWeise ergibt sich eine deutliche Leistungsoptimierung, die reguläre Ausdrückeauch zur Bearbeitung von sehr großen Zeichenketten einsetzbar macht. Dieverschiedenen Objekte, die das .NET Framework zur Bearbeitung vonZeichenketten mit regulären Ausdrücken zur Verfügung stellt, werden imNamespace System.Text.RegularExpressions zusammengefasst.

Page 153: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

8 Arbeiten mit Zeichenketten _____________________________________________153

Im Folgenden wird die Verwendung von regulären Ausdrücken prinzipiellvorgestellt. Dabei wird insbesondere auf die weiteren Unterschiede undBesonderheiten der .NET-Implementierung eingegangen. Eine darüberhinausgehende, erschöpfende Beschreibung findet sich in der entsprechendenFachliteratur.

8.3.1 Der Aufbau von regulären Ausdrücken

Als Beschreibungssprache verwenden reguläre Ausdrücke eine bestimmte Syntax,um das gewünschte Ergebnis zu definieren. Es handelt sich dabei um eineMischung aus normalen Zeichen, die für sich selbst stehen, undAnweisungszeichen, die für bestimmte Zeichengruppen oder Ausdrücke wie einenUmbruch stehen. Aus der Kombination dieser Zeichen lässt sich nahezu jede Teil-Zeichenkette beschreiben, die einem bestimmten Muster folgt.Das folgende Beispiel demonstriert, wie man mit Hilfe von regulären Ausdrückensehr einfach Dezimalzahlen aus einer Zeichenkette extrahieren kann. Die Zahlensind dabei beliebig in der Zeichenkette verstreut.

Listing 8.22 regex1.cs

using System;using System.Text.RegularExpressions;

class ConsoleApp{static void Main(){string s1 = "Addiert man 5 und 9, ergibt dies 14.";

Regex r = new Regex(@"\d");

foreach(Match m in r.Matches(s1)){Console.WriteLine(m.Value + "");}

Console.ReadLine();}}

Zahlen suchen

Page 154: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

154 _______________________________________________ 8.3 Reguläre Ausdrücke

Die Ausgabe im Konsolenfenster zeigt, dass das Beispiel funktioniert. Eineaufwändiges Parsen und Vergleichen der Zeichenkette entfällt völlig.

5914

Das Beispiel ist im Grunde sehr trivial, denn die Möglichkeiten von regulärenAusdrücken gehen sehr viel weiter. Aber dennoch zeigt das Beispiel derenAnwendung sehr gut. Der Ausdruck „\d“ kennzeichnet eine Dezimalzahl; eineeinzige. Auf diese Weise werden zusammenhängende Zahlen einzeln extrahiert,deutlich erkennbar an der Ausgabe der Zahl 14 als 1 und 4. Schöner wäre esnatürlich, wenn die tatsächliche Zahl ausgegeben würde, unabhängig, wie vieleStellen diese hat. Das Quantifizierungszeichen „+“ kann hier Abhilfe schaffen. DasZeichen kennzeichnet, dass das zuvor notierte Element (in diesem Fall „\d“) einoder mehrmals hintereinander auftauchen kann. Im Beispiel eingefügt, ergibt sichdas ursprünglich gewünschte Ergebnis.

Listing 8.23 regex2.cs

...Regex r = new Regex(@"\d+");...

Die Ausgabe im Konsolenfenster erscheint nun wie gewünscht:

5914

Mit Hilfe der vorgestellten Zeichen und Anweisungen lassen sich komplexeAusdrücke zusammenstellen. So könnte man ein Datum aus einer beliebigenZeichenkette extrahieren.

Listing 8.24 regex3.cs

using System;using System.Text.RegularExpressions;

class ConsoleApp{static void Main(){string s1 = "Heute ist der 25.08.2001, ein Samstag!";

Datum suchen

Page 155: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

8 Arbeiten mit Zeichenketten _____________________________________________155

Regex r = new Regex(@"\d{1,2}\.\d{1,2}\.\d{4}"); //

Console.WriteLine("Datum: " + r.Match(s1).Value);

Console.ReadLine();}}

Auch hier wird wieder eine Dezimalzahl extrahiert. Allerdings muss diese aus dreiBlöcken aus je 1 bis 2 Ziffern für Tag und Monat beziehungsweise 4 Ziffern für dasJahr bestehen. Hierzu wird die Anzahl nach dem Element „\d“ in geschweiftenKlammern notiert. Minimal- und maximal-Anzahl werden mit einem Kommagetrennt.Ausgabe im Konsolenfenster:

Datum: 25.08.2001

Neben „\d“ stehen eine ganze Reihe weiterer Zeichen zur Verfügung. Die Tabelleenthält eine Auflistung der wichtigsten von .NET angebotenen Zeichen undAnweisungen. Beachten Sie, dass Sie bei Sprachen wie C#, C++ und JScript denBackslash „\“ immer doppelt angeben müssen, auch beziehungsweise gerade weildiesem bei regulären Ausdrücken eine Sonderbedeutung zu Gute kommt. Bei C#können Sie hierauf verzichten, wenn Sie das @-Zeichen vor der Zeichenkettenotieren. Unter Visual Basic.NET ist keine besondere Beachtung notwendig.

Tabelle 8.5 Die wichtigsten Anweisungen und Zeichen der regulären Ausdrücke in derÜbersicht

Zeichen Beschreibung

Gewöhnliche Buchstaben Sofern die Buchstaben nicht zu . $ ^ { [ ( | ) * + ? \ gehörenentsprechen diese Zeichen sich selbst. Möchte man also nacheinem kleinen „a“ suchen, notiert man dieses auch als „a“.

\ Wird der Backslash von einem der Zeichen . $ ^ { [ ( | ) * + ?gefolgt, so entspricht die Kombination diesem Zeichen. DieSonderbedeutung des Zeichens wird auf diese Weise alsoaufgehoben.

\a Alarm-Zeichen (beep/ bell)

\b Backspace

\t Horizontaler Tabulator

\r Wagenrücklauf (Carriage return)

\v Vertikaler Tabulator

\f Zeilenvorschub (Form feed)

\n Zeilenumbruch (New line)

Page 156: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

156 _______________________________________________ 8.3 Reguläre Ausdrücke

Zeichen Beschreibung

\nnn Beliebiges ASCII-Zeichen mit der Dezimalzahl nnn

\xnn Beliebiges ASCII-Zeichen mit der Hexadezimalzahl nn

Zeichengruppen Beschreibung

\unnnn Beliebiges Unicode-Zeichen mit der Dezimalzahl nnnn

. Entspricht einem beliebigen Zeichen ausgenommen \n (Newline)

[abc] Entspricht einem der innerhalb der Klammer notierten Zeichen,also a, b oder c

[^abc] Entspricht einem beliebigen Zeichen, das nicht (!) in derKlammer notiert ist, also allen Zeichen außer a, b und c

[0-9°-zA-Z] Entspricht einem Zeichen, das innerhalb der notiertenZeichenbereiche liegt, in diesem Fall alle Zahlen sowie Klein-und Großbuchstaben

\w Entspricht jedem Wortzeichen, identisch zu [0-9a-zA-Z]

\W Entspricht jedem Zeichen, das kein Wortzeichen ist, identischzu [^0-9a-zA-Z]

\s Entspricht einem beliebigen Whitespace-Zeichen, identisch zu[\f\n\r\t\v]

\S Entspricht einem beliebigen Zeichen, das kein Whitespace-Zeichen ist, identisch zu [^ \f\n\r\t\v]

\d Entspricht einem dezimalen Zeichen, identisch zu [0-9]

\D Entspricht einem beliebigen Zeichen, das kein dezimalesZeichen ist, identisch zu [^0-9]

Meta-Zeichen Beschreibung

^ Bezeichnet den Anfang der Zeichenkette; sofern die OptionMultiLine gesetzt ist, den Anfang einer Zeile

$ Bezeichnet das Ende der Zeichenkette; sofern die OptionMultiLine gesetzt ist, das Ende einer Zeile

\A Bewirkt, dass die Übereinstimmung am Anfang derZeichenkette liegen muss, und ignoriert somit die eventuellgesetzte Option MultiLine

\z Bewirkt, dass die Übereinstimmung am Ende der Zeichenketteliegen muss, und ignoriert somit die eventuell gesetzte OptionMultiLine

\Z Bewirkt, dass die Übereinstimmung am Ende der Zeichenketteoder vor einem \n am Ende der Zeichenkette liegen muss, undignoriert somit die eventuell gesetzte Option MultiLine

Page 157: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

8 Arbeiten mit Zeichenketten _____________________________________________157

Quantifizierungszeichen Beschreibung

* Bewirkt, dass das zuvor notierte Element nicht oder beliebighäufig vorkommen kann

+ Bewirkt, dass das zuvor notierte Element mindestens einmalvorkommen muss

? Bewirkt, dass das zuvor notierte Element nicht oder einmalvorkommen muss

{n} Bewirkt, dass das zuvor notierte Element n mal vorkommenmuss

{n,} Bewirkt, dass das zuvor notierte Element mindestens n malvorkommen muss

{n,m} Bewirkt, dass das zuvor notierte Element mindestens n mal,aber maximal m mal vorkommen muss

Alternierungszeichen Beschreibung

| Das links oder das rechts notierte Element mussübereinstimmen

(?(Ausdruck)ja|nein) Entspricht dem ja-Ausdruck, sofern der in Klammern notierteAusdruck übereinstimmt, ansonsten dem optionalen Nein-Ausdruck

Gruppierungen Beschreibung

( ) Gruppiert den in Klammern eingeschlossenen Ausdruck, umeinen späteren Zugriff auf diesen Teilbereich zu ermöglichen.Der Zugriff kann sowohl innerhalb des Gesamtausdrucks alsauch später zum Beispiel bei einer Ersetzung mit Replaceerfolgen. Der Zugriff erfolgt in beiden Fällen über dienachfolgend beschriebenen Referenzen über eine fortlaufendeNummerierung.

(?<name> ) Gruppiert analog, vergibt aber einen Namen für die Referenz

Referenzen Beschreibung

\n Greift auf den Inhalt einer Gruppierung über die fortlaufendeNummer n zu, beim Ersetzen oder Zugriff über die Result-Methode des Match-Objektes wird $n angegeben

\k<name> Greift auf den Inhalt einer Gruppierung über den vergebenenNamen zu, beim Ersetzen oder Zugriff über die Result-Methodedes Match-Objektes wird ${name} angegeben

8.3.2 Die Klasse Regex

Bereits in den ersten beiden Beispielen weiter oben wurde die Klasse Regexverwendet. Sie ist Dreh- und Angelpunkt der regulären Ausdrücke innerhalb des.NET Frameworks. Die Klasse bietet Methoden zum Suchen, Ersetzen undAufsplitten von Zeichenketten an. Die meisten Methoden sind sowohl in einer

Page 158: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

158 _______________________________________________ 8.3 Reguläre Ausdrücke

statischen als auch in einer dynamischen Version verfügbar. Die dynamischeVersion auf der Basis einer Instanz der Klasse ist in der Regel vorzuziehen. Deroder die regulären Ausdrücke werden in diesem Fall einmal an den Konstruktur derKlasse übergeben. Alle Methoden-Aufrufe beziehen sich dann auf diesen Ausdruck.Auf diese Weise kann der Ausdruck fest in das Programm kompiliert und somitschneller als die Interpretation zur Laufzeit abgearbeitet werden.

IsMatch

Diese Methode wird häufig verwendet, um Validierungen durchzuführen. Dabeiwird neben einer zu prüfenden Zeichenkette ein Ausdruck übergeben, der derenAufbau beschreibt. IsMatch liefert nun zurück, ob der Ausdruck mindestens eineÜbereinstimmung ergeben hat. Fügt man dem Ausdruck zu Beginn „^“ und amEnde „$“ hinzu, kann man IsMatch verwenden, um den gesamten Ausdruck aufÜbreinstimmung zu prüfen. Ein oft verwendetes Beispiel hierfür ist die Prüfung vonE-Mail-Adressen:

Listing 8.25 ismatch1.cs

using System;using System.Text.RegularExpressions;

class ConsoleApp{public static void IsEmailOK(string email){Console.Write("Die Adresse " + email + " ist ");Regex r = new Regex(@"^.+@.+\..+$");if(r.IsMatch(email))Console.Write("korrekt");elseConsole.Write("leider nicht korrekt");Console.WriteLine("");}

static void Main(){IsEmailOK("[email protected]");IsEmailOK("test@test");IsEmailOK(",[email protected]");

Console.ReadLine();}}

E-Mail-Adresseprüfen

Page 159: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

8 Arbeiten mit Zeichenketten _____________________________________________159

Ausgabe im Konsolenfenster:

Die Adresse [email protected] ist korrektDie Adresse test@test ist leider nicht korrektDie Adresse ,[email protected] ist korrekt

Der verwendete Ausdruck ist relativ trivial, da dieser die E-Mail-Adresse lediglichnach dem Muster [email protected] überprüft. Es werden daher durchausoffensichtlich falsche E-Mail-Adressen als korrekt erkannt. Das Beispiel zeigt diesan Hand der Adresse „,[email protected]“, die ganz sicher nicht korrekt ist. Sehr vieleffektiver ist hingegen der folgende Ausdruck:

Listing 8.26 ismatch2.cs

...Regex r = new Regex(@"^[\w\.\-]+@([\w\-]+\.)*[\w\-]{2,63}\.[a-zA-Z]{2,4}$");

...

Die Ausgabe im Konsolenfenster stimmt zunächst mit der des vorangegangenenBeispiels überein. Bei der dritten E-Mail-Adresse wird jedoch deutlich, dass derhier verwendete Ausdruck wesentlich genauer ist – probieren Sie es aus!

Die Adresse [email protected] ist korrektDie Adresse test@test ist leider nicht korrektDie Adresse ,[email protected] ist leider nicht korrekt

Match

Die Methode Match wird verwendet, um einen regulären Ausdruck innerhalb einerZeichenkette zu suchen. Das Beispiel verwendet den vorherigen Ausdruck, um eineE-Mail-Adresse innerhalb einer beliebigen Zeichenkette zu suchen. Aus demAusdruck wurden allerdings die Zeichen „^“ und „$“ entfernt, da die Adresse aneiner beliebigen Stelle innerhalb der Zeichenkette vorkommen kann.

Listing 8.27 match1.cs

using System;using System.Text.RegularExpressions;

class ConsoleApp{static void Main(){string s1 = "Hallo Welt, Ihr könnte mich unter " +

ErweitertePrüfung

Einen Trefferfinden

Page 160: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

160 _______________________________________________ 8.3 Reguläre Ausdrücke

"der Adresse [email protected] erreichen.";

Regex r = new Regex(@"[\w\.\-]+@([\w\-]+\.)*[\w\-]{2,63}\.[a-zA-Z]{2,4}");Match m = r.Match(s1);

Console.WriteLine("eMail: " + m.Value);

Console.ReadLine();}}

Response.Write("eMail: " + m.Value);

Ausgabe im Konsolenfenster:

eMail: [email protected]

Matches

Die Methode Matches arbeitet ähnlich wie Match, liefert allerdings eine Collectionmit allen Fundstellen zurück. Diese lässt sich anschließend beispielsweise mit einerforeach..in-Schleife durchlaufen. Das Beispiel zeigt die Anwendung des Ausdrucksbei mehreren zu suchenden E-Mail-Adressen.

Listing 8.28 matches1.cs

using System;using System.Text.RegularExpressions;

class ConsoleApp{static void Main(){string s1 = "Hallo Welt, Ihr könnte mich unter " +"der Adresse [email protected] erreichen, " +"alternativ könnt Ihr mir auch eine eMail an [email protected] " +"schicken.";

Regex r = new Regex(@"[\w\.\-]+@([\w\-]+\.)*[\w\-]{2,63}\.[a-zA-Z]{2,4}");MatchCollection mc = r.Matches(s1);

foreach(Match m in mc)Console.WriteLine("eMail: " + m.Value + "");

Mehrere Trefferfinden

Page 161: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

8 Arbeiten mit Zeichenketten _____________________________________________161

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

eMail: [email protected]: [email protected]

Replace

Der Name erklärt schon, welchem Zwecke diese Methode dient: Ersetzungenvornehmen. Auf die Leistungsfähigkeit der regulären Ausdrücke kann hierallerdings nicht nur bei der Suche, sondern auch beim Vorgang des Ersetzenszurückgegriffen werden. Im folgenden Beispiel werden die Werte vor und nacheinem Doppelpunkt über eine Referenz vertauscht.

Listing 8.29 replace1.cs

using System;using System.Text.RegularExpressions;

class ConsoleApp{static void Main(){string s1 = "abc:def\nuvw:xyz";

Regex r = new Regex(@"(\w+)\:(\w+)");string s2 = r.Replace(s1, @"$2:$1");

Console.WriteLine(s2);

Console.ReadLine();}}

Die beiden Referenzen „$1“ und „$2“ greifen auf die Gruppierung innerhalb desregulären Ausdrucks zurück.Ausgabe im Konsolenfenster:

def:abcxyz:uvw

Page 162: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

162 _______________________________________________ 8.3 Reguläre Ausdrücke

Split

Das weiter oben bereits mehrfach verwendete Beispiel zur Aufsplittung einesSatzes in die einzelnen Wörter lässt sich auch mit regulären Ausdrücken realisieren.Dies könnte zum Beispiel wie folgt aussehen:

Listing 8.30 regex1.cs

using System;using System.Text.RegularExpressions;

class ConsoleApp{static void Main(){string s1 = "Hallo Welt, dies ist ein wirklich sinnvoller Satz";

Regex r = new Regex(@"( |,)");

foreach(string s2 in r.Split(s1)){if(s2.Trim().Length>0)Console.WriteLine("Wort: " + s2 + "");

}

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Wort: HalloWort: WeltWort: ,Wort: diesWort: istWort: einWort: wirklichWort: sinnvollerWort: Satz

Vielleicht fragen Sie sich, warum eine if-Abfrage vor der Ausgabe notwendig ist.Ich frage mich das auch, denn eigentlich würde ich davon ausgehen, dass dieSeparatoren analog zu anderen Split-Methoden ausgelassen würden. Dies ist aberleider nicht der Fall. Verzichtet man auf die Abfrage, ergibt sich das folgende,inkonsistente Ergebnis:

Page 163: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

8 Arbeiten mit Zeichenketten _____________________________________________163

Wort: HalloWort:Wort: WeltWort: ,Wort:Wort:Wort: diesWort:Wort: istWort:Wort: einWort:Wort: wirklichWort:Wort: sinnvollerWort:Wort: Satz

Die Methoden in der Übersicht

Die Tabelle enthält eine Übersicht der statischen und dynamischen Methoden derKlasse Regex. Die statischen Methoden sind mit einem * gekennzeichnet undmüssen über den Klassennamen, die dynamischen über eine Instanz der Klasseaufgerufen werden.

Tabelle 8.6 Die Methoden der Klasse Regex im Überblick

Methode Rückgabewert Beschreibung

CompileToAssembly* - Kompiliert eine Regex-Klasse als MSIntermediate Language und legt diese als Datei(Assembly) auf der Festplatte ab.

Escape* string Konvertiert alle Zeichen mit Sonderbedeutung (\,*, +, ?, |, {, [, (,), ^, $, ., #) einer normalenZeichenkette in die entsprechenden maskiertenZeichen.

IsMatch* bool Prüft, ob ein regulärer Ausdruck mindestenseinmal auf eine übergebene Zeichenkette zutrifft.

Match* Match Sucht den regulären Ausdruck in derübergebenen Zeichenkette und gibt die ersteFundstelle (optional: ab einer bestimmtenPosition) zurück.

Matches* MatchCollection Gibt analog zu Match eine MatchCollection mitallen Fundstellen zurück.

Replace* string Ersetzt Zeichen in einer Zeichenkette mit anderenauf Basis von regulären Ausdrücken.

Page 164: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

164 _______________________________________________ 8.3 Reguläre Ausdrücke

Methode Rückgabewert Beschreibung

Split* string[] Splittet eine Zeichenkette in mehrereBestandteile; die Separatoren werden alsregulärer Ausdruck übergeben.

Unescape* string Konvertiert die maskierten Zeichen einesregulären Ausdrucks in die regulären Zeichen undstellt somit das Gegenstück zur Methode Escapedar.

GetGroupNames string[] Liefert ein Array mit den Namen aller Gruppen derFundstellen.

GetGroupNumbers int[] Liefert ein Array mit den Nummern aller Gruppender Fundstellen.

GroupNameFrom-Number

string Liefert den Namen einer Gruppe über derenNummer.

GroupNumberFrom-Name

int Liefert die Nummer einer Gruppe über derenNamen.

IsMatch bool Arbeitet analog zur gleichnamigen statischenMethode auf Basis der aktuellen Instanz; dieÜbergabe eines regulären Ausdrucks alsParameter entfällt.

Match Match Arbeitet analog zur gleichnamigen statischenMethode auf Basis der aktuellen Instanz; dieÜbergabe eines regulären Ausdrucks alsParameter entfällt.

Matches MatchCollection Arbeitet analog zur gleichnamigen statischenMethode auf Basis der aktuellen Instanz; dieÜbergabe eines regulären Ausdrucks alsParameter entfällt.

Replace string Arbeitet analog zur gleichnamigen statischenMethode auf Basis der aktuellen Instanz; dieÜbergabe eines regulären Ausdrucks alsParameter entfällt.

Split string[] Arbeitet analog zur gleichnamigen statischenMethode auf Basis der aktuellen Instanz; dieÜbergabe eines regulären Ausdrucks alsParameter entfällt.

8.3.3 Die Regex-Optionen

Neben dem regulären Ausdruck können dem Konstruktur der Regex-Klasse eineReihe von Optionen übergeben werden. Diese werden von dem EnumeratorRegexOptions angeboten und bitweise verodert an den Konstruktor übergeben.Später lassen sich die gesetzten Optionen über die Eigenschaft Options abfragen,

Page 165: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

8 Arbeiten mit Zeichenketten _____________________________________________165

allerdings nicht mehr ändern! Die Tabelle zeigt die zur Verfügung stehendenOptionen in der Übersicht.

Tabelle 8.7 Die RegexOptions in der Übersicht

Option Beschreibung

Compiled Bestimmt, ob der reguläre Ausdruck kompiliert oder zur Laufzeitinterpretiert werden soll

ExplicitCapture Bestimmt, dass nur explizit benannte oder nummerierte Gruppenin die GroupCollection der Match-Klasse aufgenommen werdensollen. Dies ermöglicht, Klammern zur Gliederung vonAusdrücken zu verwenden, ohne dass diese als Gruppen definiertwerden.

IgnoreCase Bestimmt, dass die Groß-/ Kleinschreibung ignoriert wird

IgnorePatternWhitespace Entfernt unmaskierte Whitespaces aus dem übergebenenAusdruck

Multiline Ändert die Bedeutung der Zeichen „^“ und „$“. Ist die Optiongesetzt, beziehen sich diese Zeichen nicht auf Anfang und Endeder gesamten Zeichenkette, sondern nur auf jede einzelne Zeile.

None Setzt alle Optionen zurück

RightToLeft Bestimmt, ob die Suche von rechts nach links erfolgt soll

Singleline Ändert die Bedeutung des Zeichens „.“, sodass dieses auf jedesbeliebige Zeichen (einschließlich \n) zutrifft

Das folgende Beispiel zeigt die Verwendung der Optionen MultiLine undRightToLeft. Es soll von rechts nach links nach allen Zeilen gesucht werden, dienicht mit einer Raute beginnen und somit als Kommentar gekennzeichnet sind.

Listing 8.31 regexoptions1.cs

using System;using System.Text.RegularExpressions;

class ConsoleApp{static void Main(){string s1 = "# 1. Kommentar\n1. Zeile mit Text\n" +"2. Zeile mit Text\n# 2. kommentar";

RegexOptions ro = RegexOptions.Multiline | RegexOptions.RightToLeft;Regex r = new Regex(@"^[^#].+", ro);

Multiline undRightToLeft

Page 166: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

166 _______________________________________________ 8.3 Reguläre Ausdrücke

foreach(Match m in r.Matches(s1))Console.WriteLine("Zeile: " + m.Value + "");

Console.ReadLine();}}

Die Ausgabe im Konsolenfenster zeigt nicht nur, dass die Erkennung der einzelnenZeilen funktioniert, sondern auch, dass die Suche von rechts nach links erfolgt ist –die zweite Zeile steht vor der ersten:

Zeile: 2. Zeile mit TextZeile: 1. Zeile mit Text

8.3.4 Erweiterte Parsing-Möglichkeiten

Als Ergänzung zu den gängigen Möglichkeiten von regulären Ausdrücken bietetdas .NET Framework weitergehende Möglichkeiten zum Parsen von Zeichenkettenan. Die Basis hierzu liefern benannte Gruppierungen innerhalb eines regulärenAusdrucks. Diese Gruppierungen werden in der Form (?<name>Ausdruck) notiert.Der Zugriff auf die einzelnen Elemente erfolgt über die Groups-Eigenschaft desMatch-Objektes. Diese Eigenschaft liefert eine GroupCollection, die den Zugriffauf die einzelnen Gruppen in Form der Group-Klasse erlaubt. Da es sich um eineCollection handelt, kann der Indexer [..] verwendet werden.Das folgende Beispiel sucht eine E-Mail-Adresse aus einem Text – das kennen Sieja. Die Adresse wird aber in diesem Fall in die Elemente Benutzername („user“),Domain („domain“) und Top-Level-Domain („tld“) gruppiert. Die einzelnenElemente werden anschließend im Konsolenfenster ausgegeben.

Listing 8.32 parsing1.cs

using System;using System.Text.RegularExpressions;

class ConsoleApp{static void Main(){string s1 = "Hallo Welt, Ihr könnte mich unter " +"der Adresse [email protected] erreichen.";

Regex r = new Regex(@"(?<user>[\w\.\-]+)@(?<domain>([\w\-]+\.)*[\w\-]{2,63})\.(?<tld>[a-zA-Z]{2,4})");Match m = r.Match(s1);

eMail zerlegen

Page 167: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

8 Arbeiten mit Zeichenketten _____________________________________________167

Console.WriteLine("eMail: " + m.Value + "");Console.WriteLine("Benutzer: " + m.Groups["user"].Value + "");Console.WriteLine("Domain: " + m.Groups["domain"].Value + "");Console.WriteLine("TLD: " + m.Groups["tld"].Value + "");

Console.ReadLine();}}

Die einzelnen Elemente der E-Mail-Adresse werden korrekt erkannt und wie folgtim Konsolenfenster ausgegeben:

eMail: [email protected]: feedbackDomain: csharp-shortcutTLD: de

Auch im folgenden Beispiel werden Gruppierungen verwenden. Der Zugriff erfolgtin diesem Fall allerdings über die Result-Methode der Match-Klasse. Auch hierlassen sich die Gruppierungen einfach abfragen. Die Syntax lautet $n für denZugriff über die Gruppierungsnummer oder $[name} für den Zugriff über denvergebenen Namen.

Listing 8.33 parsing3.cs

using System;using System.Text.RegularExpressions;

class ConsoleApp{static void Main(){string s1 = "http://www.combit.net:80/";

Regex r = new Regex(@"^(?<proto>\w+)://[^/]+?:(?<port>\d+)?/",RegexOptions.Compiled);string s2 = r.Match(s1).Result("${proto}:${port}");

Console.WriteLine(s2);Console.ReadLine();}}

Ausgabe im Konsolenfenster:

http:80

URL zerlegen

Page 168: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2
Page 169: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

9Erweiterte Datentypen

Arrays

Collections

Strukturen

Aufzählungen

Page 170: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

170 ___________________________________________________________________

Inhaltsübersicht Kapitel 9

9 Erweiterte Datentypen ....................................................................................171

9.1 Arrays ................................................................................................................1719.1.1 Initialisierung und Zugriff auf Arrays................................................................1719.1.2 Mehrdimensionale Arrays .................................................................................1749.1.3 Eigenschaften und Methoden der Array-Klasse ................................................1779.2 Collections.........................................................................................................1819.2.1 ArrayList ...........................................................................................................1829.2.2 Hashtable ...........................................................................................................1839.2.3 Queue ................................................................................................................1859.2.4 SortedList ..........................................................................................................1879.2.5 Stack ..................................................................................................................1889.3 Strukturen ..........................................................................................................1899.4 Aufzählungen ....................................................................................................1929.4.1 Standard-Aufzählungen .....................................................................................1929.4.2 Flag-Aufzählungen ............................................................................................194

Page 171: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

___________________________________________________________________ 171

9 Erweiterte Datentypen

9.1 Arrays

In den bisher vorgestellten Datentypen konnte jeweils ein Element abgelegt werden.Möchte man mehrere Elemente des gleichen Typs ablegen, kann man entwederjeweils eine separate Variable anlegen oder ein Datenfeld verwenden. DieseDatenfelder nennt man Arrays. Alle Elemente werden hier unter einemgemeinsamen Variablennamen abgelegt. Der Zugriff erfolgt über diesen Namensowie einen fortlaufenden Index des jeweiligen Elements, immer beginnend bei 0.Arrays können von beliebigen Datentypen gebildet werden. Handelt es sich umeinen Wertetyp, werden die Werte direkt im Array abgelegt, bei Verweistypenwerden die jeweiligen Verweise im Array gespeichert.

9.1.1 Initialisierung und Zugriff auf Arrays

Ein Array wird wie eine reguläre Variable deklariert, es erfolgt lediglich nach demDatentyp eine eckige Klammer auf und zu. Im Folgenden wird ein Array desDatentyps string deklariert. Die Größe des Arrays wird hierbei noch nichtangegeben. Das Array enthält zunächst keine Daten, sondern verweist auf null.

string[] s;

Die Initialisierung der hinterlegten Werte kann auf zweierlei Weisen geschehen.Entweder es wird mit Hilfe des Schlüsselwortes new ein neues Array von einemDatentyp erstellt. Hierbei wird auch die Größe des Arrays angegeben. Alternativkönnen die einzelnen Elemente dem Array direkt zugewiesen werden. Die Angabeder Werte erfolgt Komma-separiert in geschweiften Klammern. Die notwendigeGröße ermittelt das Array selbstständig, auf diese Angabe kann daher verzichtetwerden.

Datenfelder

Page 172: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

172 __________________________________________________________ 9.1 Arrays

Intitialisierung mit new:

string[] s1 = new string[2];

Direkte Zuweisung:

string[] s1 = {"xxx", "yyy"};

Initialisiert man ein Array über das Schlüsselwort new, so müssen die Inhalteseparat zugewiesen werden. Hierzu bietet jedes Array einen Indexer an. In eckigenKlammern wird hierbei der fortlaufende und immer bei 0 beginnende Indexangegeben. Ist ein Array wie im vorliegenden Beispiel auf 2 Elemente initialisiert,so erfolgt der Zugriff über den Index 0 bis 1.

string[] s1 = new string[2];s1[0] = "xxx";s1[1] = "yyy";

Auch der spätere Lesezugriff auf die Elemente eines Arrays erfolgt über denIndexer. Das folgende Beispiel gibt die zuvor initialisierten Elemente eines string-Arrays im Konsolenfenster aus.

Listing 9.1 arrays1.cs

using System;

class ConsoleApp{static void Main(){string[] s1 = new string[2];s1[0] = "xxx";s1[1] = "yyy";

// Alternativ:// string[] s1 = {"xxx", "yyy"};

Console.WriteLine(s1[0] + "");Console.WriteLine(s1[1] + "");

Console.ReadLine();}}

new

DirekteZuweisung

Indexer

Page 173: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

9 Erweiterte Datentypen ________________________________________________173

Ausgabe im Konsolenfenster:

xxxyyy

Es gibt aber auch andere Möglichkeiten, um auf die Elemente zuzugreifen. Durchden fortlaufenden Index bietet sich insbesondere eine for-Schleife an. Um alsobeispielsweise alle Elemente des zuvor initialisierten string-Arrays auszugeben,kann man eine for-Schleife wie folgt verwenden.

Listing 9.2 arrays2.cs

using System;

class ConsoleApp{static void Main(){string[] s1 = new string[2];s1[0] = "xxx";s1[1] = "yyy";

// Alternativ:// string[] s1 = {"xxx", "yyy"};

for(int i=0; i<s1.Length; i++)Console.WriteLine(s1[i] + "");

Console.ReadLine();}}

Die Ausgabe im Konsolenfenster ist identisch zum vorherigen Beispiel. DieVorteile von Arrays werden hier aber wesentlich deutlicher, denn es istvollkommen irrelevant, ob das Array 2, 200 oder 2000 Elemente enthält. DieSchleife zur Ausgabe ist in jedem Fall identisch. Die Größe des Arrays wird überdie Eigenschaft Length abgefragt. Beachten Sie, dass diese Eigenschaft nur beieindimensionalen Arrays verwendet werden kann. Bei mehrdimensionalen Arraysliefert die Eigenschaft die Gesamtanzahl aller Elemente in allen Dimension zurück.Mehr zu mehrdimensionalen Arrays finden Sie weiter unten.Eine alternative Möglichkeit zum Durchlaufen aller Elemente eines Arrays ist dieforeach..in-Schleife. Die Ausgabe des folgenden Beispiels ist mit den vorherigenidentisch, man spart sich allerdings die Index-Variable i und überhaupt wird besserdeutlich, dass man alle Elemente des Arrays durchlaufen möchte: „Für jeden strings2 im Array s1...“.

for-Schleife

foreach..in

Page 174: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

174 __________________________________________________________ 9.1 Arrays

Listing 9.3 arrays3.cs

using System;

class ConsoleApp{static void Main(){string[] s1 = new string[2];s1[0] = "xxx";s1[1] = "yyy";

// Alternativ:// string[] s1 = {"xxx", "yyy"};

foreach(string s2 in s1)Console.WriteLine(s2 + "");

Console.ReadLine();}}

9.1.2 Mehrdimensionale Arrays

Die bisher vorgestellten Arrays haben Elemente in einer Dimension abgelegt. Eskönnen aber auch mehrdimensionale Arrays angelegt werden, bei denen der Zugriffauf einzelne Elemente nicht über einen Index, sondern über mehrere erfolgt. Esentsteht eine Matrix, die mit einem Koordinatensystem vergleichbar ist; um einenPunkt zu beschreiben, benötigt man den x- und den y-Wert. Auch bei derDeklaration eines mehrdimensionalen Arrays müssen alle Dimensionen angegebenwerden.

Listing 9.4 arrays1.cs

using System;

class ConsoleApp{static void Main(){string[,] s1 = new string[2, 2];s1[0, 0] = "xxx";s1[0, 1] = "abc";s1[1, 0] = "yyy";s1[1, 1] = "def";

Page 175: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

9 Erweiterte Datentypen ________________________________________________175

// Alternativ://string[,] s1 = {{"xxx", "abc"}, {"yyy", "def"}};

Console.WriteLine(s1[0, 0] + "");Console.WriteLine(s1[0, 1] + "");Console.WriteLine(s1[1, 0] + "");Console.WriteLine(s1[1, 1] + "");

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

xxxabcyyydef

Auch bei mehrdimensionalen Arrays können Schleifen verwendet werden, um diesezu durchlaufen. Im Falle einer for-Schleife benötigt man zwei Schleifen mit zweiIndex-Variablen.

Listing 9.5 arrays2.cs

using System;

class ConsoleApp{static void Main(){string[,] s1 = new string[2, 2];s1[0, 0] = "xxx";s1[0, 1] = "abc";s1[1, 0] = "yyy";s1[1, 1] = "def";

// Alternativ://string[,] s1 = {{"xxx", "abc"}, {"yyy", "def"}};

for(int i=0; i<s1.GetLength(0); i++){for(int j=0; j<s1.GetLength(1); j++)Console.WriteLine(s1[i,j] + "");

}

for-Schleife

Page 176: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

176 __________________________________________________________ 9.1 Arrays

Console.ReadLine();}}

Die Ausgabe im Konsolenfenster ist erneut identisch.Auch die Verwendung einer foreach..in-Schleife ist möglich. Hier benötigt manallerdings wie im Fall eines eindimensionalen Arrays nur eine Schleife. foreach..inliefert in jedem Fall alle Elemente und durchläuft das Array im Fall mehrererDimensionen von oben nach unten und links nach rechts.

Listing 9.6 arrays3.cs

using System;

class ConsoleApp{static void Main(){string[,] s1 = new string[2, 2];s1[0, 0] = "xxx";s1[0, 1] = "abc";s1[1, 0] = "yyy";s1[1, 1] = "def";

// Alternativ://string[,] s1 = {{"xxx", "abc"}, {"yyy", "def"}};

foreach(string s2 in s1)Console.WriteLine(s2 + "");

Console.ReadLine();}}

Auch hier ergibt sich die identische Ausgabe im Konsolenfenster:

xxxabcyyydef

foreach..in

Page 177: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

9 Erweiterte Datentypen ________________________________________________177

9.1.3 Eigenschaften und Methoden der Array-Klasse

Ein Array ist im Grunde nichts anderes als ein spezieller Datentyp, der durch dieKlasse mit dem Namen Array repräsentiert wird. Wie jede Klasse verfügt auch dasArray über Eigenschaften und Methoden. Eine Auswahl interessanter Mitgliederwird im Folgenden vorgestellt. Eine Übersicht finden Sie in der Tabelle weiterunten. Statische Methoden sind mit einem * gekennzeichnet.

IndexOf*

Die statische Methode liefert den ersten Index eines bestimmten Objektes in einemeindimensionalen Array zurück. Es handelt sich also um eine Möglichkeit, einArray zu durchsuchen. Intern wird für jedes Element die von object abgeleiteteMethode Equals aufgerufen. Es hängt daher vom Typ der Elemente ab, ob derWert oder der Verweis verglichen wird. Im nachfolgenden Beispiel wird in einemstring-Array gesucht. Hier wird der Wert verglichen.

Listing 9.7 indexof1.cs

using System;

class ConsoleApp{static void Main(){string[] s1 = new string[4];s1[0] = "xxx";s1[1] = "yyy";s1[2] = "aaa";s1[3] = "bbb";

int i = Array.IndexOf(s1, "yyy");

Console.WriteLine("Der gesuchte String befindet sich " +"an der Position " + i.ToString());

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Der gesuchte String befindet sich an der Position 1

Position ermitteln

Page 178: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

178 __________________________________________________________ 9.1 Arrays

Wird das übergebene Objekt nicht gefunden, liefert die Methode –1 zurück. Aufdiese Weise lässt sich sehr einfach eine Contains-Methode realisieren.

Listing 9.8 indexof2.cs

using System;

class ConsoleApp{public static void Contains(object[] arr, object value){Console.Write("Das Objekt " + value.ToString() + " ist ");if(Array.IndexOf(arr, value)==-1)Console.Write("nicht ");Console.Write("im Array enthalten\n");}

static void Main(){string[] s1 = new string[4];s1[0] = "xxx";s1[1] = "yyy";s1[2] = "aaa";s1[3] = "bbb";

Contains(s1, "abc");Contains(s1, "yyy");

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Das Objekt abc ist nicht im Array enthaltenDas Objekt yyy ist im Array enthalten

Weitere Suchmöglichkeiten stehen mit den Methoden BinarySearch undLastIndexOf zur Verfügung.

Reverse*

Auch diese Methode ist statisch in der Klasse Array implementiert. Sie dreht dieOrdnung der Elemente eines übergebenen eindimensionalen Arrays um. Das ersteElement steht anschließend an letzter Stelle, das letzte an erster.

Enthält?

Array umdrehen

Page 179: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

9 Erweiterte Datentypen ________________________________________________179

Listing 9.9 reverse1.cs

using System;

class ConsoleApp{static void Main(){string[] s1 = new string[4];s1[0] = "xxx";s1[1] = "yyy";s1[2] = "aaa";s1[3] = "bbb";

Array.Reverse(s1);

foreach(string s2 in s1)Console.WriteLine(s2 + "");

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

bbbaaayyyxxx

Sort*

Die Methode Sort ändert ebenfalls die Reihenfolge der Elemente eineseindimensionalen Arrays. Allerdings werden diese entsprechend Ihrem Inhaltalphanumerisch sortiert.

Listing 9.10 sort1.cs

using System;

class ConsoleApp{static void Main(){string[] s1 = new string[4];s1[0] = "xxx";s1[1] = "yyy";

Array sortieren

Page 180: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

180 __________________________________________________________ 9.1 Arrays

s1[2] = "aaa";s1[3] = "bbb";

Array.Sort(s1);

foreach(string s2 in s1)Console.WriteLine(s2 + "");

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

aaabbbxxxyyy

Übersicht

Die folgenden beiden Tabellen enthalten alle Eigenschaften und Methoden derArray-Klasse in der Übersicht. Statische Methoden sind mit einem *gekennzeichnet. Diese Methoden werden über den Namen der Klasse, Array,aufgerufen, alle anderen Methoden werden über eine Instanz der Klasse aufgerufen.

Tabelle 9.1 Die Eigenschaften der Array-Klasse in der Übersicht

Eigenschaft Rückgabewert Beschreibung

IsFixedSize bool Gibt zurück, ob das Array eine feste Größe hat.

IsReadOnly bool Gibt zurück, ob das Array schreibgeschützt ist.

Length int Gesamtanzahl aller Elemente eines Arrays.

Rank int Anzahl der Dimensionen eines Arrays minus 1; beieindimensionalen Arrays immer 0.

Tabelle 9.2 Die Methoden der Array-Klasse in der Übersicht

Methode Rückgabewert Beschreibung

BinarySearch* int Sucht einen übergebenen Wert binär in einem Array undliefert den Index der ersten Fundstelle zurück.

Clear* - Setzt den Inhalt eines Arrays komplett zurück.

IndexOf* int Sucht ein übergebenes Objekt in einem Array und liefertden Index der ersten Fundstelle zurück.

Page 181: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

9 Erweiterte Datentypen ________________________________________________181

Methode Rückgabewert Beschreibung

LastIndexOf* int Sucht ein übergebenes Objekt in einem Array und liefertden Index der letzten Fundstelle zurück.

Reverse* - Dreht die Anordnung aller Elemente eineseindimensionalen Arrays um; das erste Element stehtanschließend an letzter Stelle, das letzte an erster.

Sort* - Sortiert alle Elemente eines eindimensionalen Arrays.

GetLength int Gibt die Anzahl der Elemente in einer angegebenenDimension. Es wird der Index der Dimension beginnendbei 0 angegeben. Bei eindimensionalen Arrays kannalternativ die Eigenschaft Length verwendet werden.

GetLowerBound int Gibt die untere Begrenzung einer Dimension des Arrayszurück, muss immer 0 sein.

GetUpperBound int Gibt die obere Begrenzung einer Dimension des Arrayszurück, entspricht immer GetLength–1

GetValue object Gibt den Inhalt eines angegebenen Elements des Arrayszurück. Der Zugriff kann analog auch über den Indexererfolgen, daher ist die Verwendung dieser Methoden inder Regel nicht notwendig.

Initialize - Initialisiert alle einzelnen Elemente eines Arrays explizit,indem es den jeweiligen Konstruktur aufruft.

SetValue - Setzt den Inhalt eines angegebenen Elements desArrays. Der Zugriff kann analog auch über den Indexererfolgen, daher ist die Verwendung dieser Methoden inder Regel nicht notwendig.

9.2 Collections

Innerhalb des Namespaces System.Collection fasst das .NET Framework eine ganzeReihe von unterschiedlichen Collections und Listen zusammen. Die einzelnenKlassen unterscheiden sich in der Art und Weise, wie die Elemente abgelegt undwie wieder auf diese zugegriffen werden kann. Die Tabelle fasst einige wichtigeCollections zusammen.

Tabelle 9.3 Wichtige Collections in der Übersicht

Collection Beschreibung

ArrayList Stellt ein dynamisches Array zur Verfügung, zu dem Elemente hinzugefügtund auch wieder entfernt werden können.

Hashtable Stellt eine Hashtable zur Verfügung, bei der Elemente mit einem Namenversehen werden können. Der Zugriff auf die Elemente kann anschließendüber den vergebenen Namen erfolgen.

Page 182: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

182 ______________________________________________________ 9.2 Collections

Collection Beschreibung

Queue Stellt eine Queue nach dem First-in-first-out-Prinzip (fifo) zur Verfügung.Elemente werden an die Collection angehängt und können später hierherausgenommen werden. Hierbei wird das Objekt aus der Queue entfernt.

SortedList Arbeitet ähnlich wie eine Hashtable, stellt die Elemente aber sortiert nachderen Elementnamen zur Verfügung.

Stack Dieses Gegenstück zur Queue implementiert eine Collection nach demLast-in-first-out-Prinzip (lifo). Der letzte hinzugefügte Wert wird als Ersterwieder herausgenommen.

9.2.1 ArrayList

Die ArrayList stellt ein dynamisches Array zur Verfügung, zu dem Elementehinzugefügt und auch wieder entfernt werden können. Der Zugriff erfolgt über denIndex oder über eine foreach..in-Schleife

Listing 9.11 arraylist1.cs

using System;using System.Collections;

class ConsoleApp{static void Main(){ArrayList al = new ArrayList();al.Add("Hallo");al.Add("Welt");al.Add("!");

for(int i=0; i<al.Count; i++)Console.WriteLine(al[i] + "");

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

HalloWelt!

DynamischesArray

Page 183: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

9 Erweiterte Datentypen ________________________________________________183

Listing 9.12 arraylist2.cs

using System;using System.Collections;

class ConsoleApp{static void Main(){ArrayList al = new ArrayList();al.Add("Hallo");al.Add("Welt");al.Add("!");

foreach(string s in al)Console.WriteLine(s + "");

Console.ReadLine();}}

Die Ausgabe im Konsolenfenster ist identisch.

9.2.2 Hashtable

Die Hashtable stellt eine Liste zur Verfügung, bei der Elemente mit einemeindeutigen Namen versehen werden können. Der Zugriff auf die Elemente kannanschließend über den vergebenen Namen erfolgen.

Listing 9.13 hastable1.cs

using System;using System.Collections;

class ConsoleApp{static void Main(){Hashtable ht = new Hashtable();ht.Add("Wort 1", "Hallo");ht.Add("Wort 2", "Welt");ht.Add("Wort 3", "!");

Console.WriteLine(ht["Wort 1"] + "");Console.WriteLine(ht["Wort 2"] + "");Console.WriteLine(ht["Wort 3"] + "");

Page 184: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

184 ______________________________________________________ 9.2 Collections

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

HalloWelt!

Alternativ ist auch bei Hashtables der Zugriff über eine foreach..in-Schleifemöglich. Hierbei kommt das Objekt DictionaryEntry zum Einsatz, das eineneinzelnen Eintrag repräsentiert. Man kann sich bei einer Hashtable allerdings nichtdarauf verlassen, dass die übergebenen Werte in der Reihenfolge der Ablagegespeichert werden. Im folgenden Beispiel ergibt sich daher eine geänderteAusgabe.

Listing 9.14 hashtable2.cs

using System;using System.Collections;

class ConsoleApp{static void Main(){Hashtable ht = new Hashtable();ht.Add("Wort 1", "Hallo");ht.Add("Wort 2", "Welt");ht.Add("Wort 3", "!");

foreach(DictionaryEntry de in ht)Console.WriteLine(de.Value + "");

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Welt!Hallo

foreach..in

Page 185: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

9 Erweiterte Datentypen ________________________________________________185

Die Hashtable-Klasse implementiert die IDictionaryEnumerator-Schnittstelle. Aufdiese Weise ist ein Zugriff über eine Aufzählung (Enumerator) ähnlich wie beimDurchlaufen einer Tabelle möglich. Die Ausgabe im Konsolenfenster ist hier analogzum vorherigen Beispiel scheinbar unsortiert.

Listing 9.15 hashtable3.cs

using System;using System.Collections;

class ConsoleApp{static void Main(){Hashtable ht = new Hashtable();ht.Add("Wort 1", "Hallo");ht.Add("Wort 2", "Welt");ht.Add("Wort 3", "!");

IDictionaryEnumerator denum = ht.GetEnumerator();

while(denum.MoveNext())Console.WriteLine(denum.Key + ": " + denum.Value + "");

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Wort 2: WeltWort 3: !Wort 1: Hallo

9.2.3 Queue

Eine Queue wird in der Regel zur Abarbeitung von Aufträgen verwendet. DieAufträge werden dabei in der Queue abgelegt (Methode Enqueue) und zumZeitpunkt der Verarbeitung wieder abgeholt (Methode Dequeue). Das ersteElement, das abgelegt wird, ist auch das erste Element, das wieder abgeholt wird.Es entsteht ein Ringpuffer nach dem First-in-first-out-Prinzip (fifo).

Enumerator

first-in-first-out

Page 186: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

186 ______________________________________________________ 9.2 Collections

Listing 9.16 queue1.cs

using System;using System.Collections;

class ConsoleApp{static void Main(){Queue q = new Queue();q.Enqueue("Hallo");q.Enqueue("Welt");q.Enqueue("!");

while(q.Count>0){string s = (string) q.Dequeue();Console.WriteLine(s + "");}

Console.ReadLine();}}

Ausgabe im Konsolenfenster :

HalloWelt!

Mit Hilfe der Eigenschaft Count und einer while-Schleife lassen sich die Elementesehr gut abarbeiten, denn durch den Aufruf von Dequeue wird das Element nichtnur abgefragt, sondern auch aus der Queue entfernt. Möchte man allerdingslediglich auf das Objekt zugreifen und dieses nicht aus der Queue löschen, kann dieMethode Peek verwendet werden. Diese fragt das oberste Element der Queue abund verändert die Queue nicht. Der Zugriff auf die weiteren Elemente der Queue istauf diese Weise nicht möglich.

Listing 9.17 queue2.cs

using System;using System.Collections;

class ConsoleApp{static void Main(){Queue q = new Queue();

Page 187: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

9 Erweiterte Datentypen ________________________________________________187

q.Enqueue("Hallo");q.Enqueue("Welt");q.Enqueue("!");

string s = (string) q.Peek();Console.WriteLine(s + "");

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Hallo

9.2.4 SortedList

Die Klasse SortedList arbeitet ähnlich wie die Hashtable. Auch hier werden miteinem eindeutigen Namen versehene Elemente abgelegt. Der Zugriff ist auch hierüber den Namen sowie den Index möglich. Dieser Index und somit die Anordnungder Elemente innerhalb der Collection erfolgt automatisch sortiert nach demNamen.Obwohl im folgenden Beispiel die Werte unsortiert übergeben werden, erfolgt dieAusgabe in der richtigen Reihenfolge. Auch hier kommt die DictionaryEntry-Klasse zum Einsatz, die einen einzelnen Eintrag in der SortedList repräsentiert.

Listing 9.18 sortedlist1.cs

using System;using System.Collections;

class ConsoleApp{static void Main(){SortedList sl = new SortedList();sl.Add("Wort 2", "Welt");sl.Add("Wort 3", "!");sl.Add("Wort 1", "Hallo");

foreach(DictionaryEntry de in sl)Console.WriteLine(de.Value + "");

Page 188: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

188 ______________________________________________________ 9.2 Collections

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

HalloWelt!

9.2.5 Stack

Der Stack ist das Gegenstück zur Queue. Die Klasse geht ähnlich vor,implementiert die Collection allerdings nach dem Last-in-first-out-Prinzip (lifo).Der letzte hinzugefügte Wert wird als Erster wieder herausgenommen.Zum Ablegen eines neuen Elements wird die Methode Push verwendet. DieMethode Pop fragt ein Element ab und löscht dieses aus dem Stack. Die MethodePeek fragt wie bei der Klasse Queue den obersten Wert ab, löscht ihn aber nicht.

Listing 9.19 stack1.cs

using System;using System.Collections;

class ConsoleApp{static void Main(){Stack st = new Stack();st.Push("Hallo");st.Push("Welt");st.Push("!");

while(st.Count>0){string s = (string) st.Pop();Console.WriteLine(s + "");}

Console.ReadLine();}}

last-in-first-out

Page 189: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

9 Erweiterte Datentypen ________________________________________________189

Da nach dem lifo-Prinzip gearbeitet wird, erfolgt die Ausgabe umgekehrt zurAblage. Ausgabe im Konsolenfenster:

!WeltHallo

9.3 Strukturen

Strukturen sind Klassen sehr ähnlich, unterscheiden sich aber intern in einemwichtigen Punkt. Strukturen sind Wertetypen und nicht wie Klassen Verweistypen.Aus diesem Grund eignen sich Strukturen besonders für kleine Datenmengen, diewie ein Datentyp behandelt werden sollen und auf diese Weise unter Umständensehr häufig in einem Programm verwendet werden. Die Syntax von Strukturenentspricht der von Klassen, sie werden im Unterschied zu diesen aber mit demSchlüsselwort struct eingeleitet.Das folgende Beispiel zeigt ein sehr häufig verwendetes Beispiel für eine Struktur.Zwei Dezimalwerte x und y sollen einen Punkt (Point) in einem Koordinatensystemrepräsentieren.

Listing 9.20 struct1.cs

using System;

class ConsoleApp{public struct Point{public int x;public int y;}

static void Main(){Point p = new Point();p.x = 15;p.y = 9;

Console.WriteLine("x: " + p.x.ToString() + "");Console.WriteLine("y: " + p.y.ToString() + "");

Console.ReadLine();}}

EigeneDatentypen

Page 190: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

190 _______________________________________________________ 9.3 Strukturen

Ausgabe im Konsolenfenster:

x: 15y: 9

Die Syntax von Strukturen entspricht – wie beschrieben – der von Klassen. Insofernkönnen Sie durchaus auch einen Konstruktor definieren, dem die Werte für x und yübergeben werden. Es ist allerdings nicht möglich, einen Konstruktor ohneParameter explizit zu deklarieren. Dieser wird von .NET implizit angenommen.Alle Werte werden in diesem Fall auf null gesetzt. Eine explizite Deklaration dereinzelnen Werte ist ebenfalls nicht möglich.

Listing 9.21 struct2.cs

using System;

class ConsoleApp{public struct Point{public int x;public int y;

public Point(int x, int y){this.x = x;this.y = y;}}

static void Main(){Point p = new Point(15, 9);

Console.WriteLine("x: " + p.x.ToString() + "");Console.WriteLine("y: " + p.y.ToString() + "");

Console.ReadLine();}}

Die Ausgabe entspricht dem vorigen Beispiel. Das Schlüsselwort this im neuangelegten Konstruktur ist notwendig, damit deutlich wird, dass sich die Zuweisungauf das Element der Struktur und nicht auf die gleichnamige lokale Variablebezieht.

Ein Punkt alsDatentyp

Page 191: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

9 Erweiterte Datentypen ________________________________________________191

Oft wird auch die von object implizit geerbte ToString-Methode überschrieben.Das folgende Beispiel zeigt, wie x und y über eine implizite Typenumwandlungformatiert ausgegeben werden. Mit Ausnahme dieser impliziten Vererbung ist esübrigens nicht möglich, Strukturen von anderen Klassen oder Strukturen abzuleiten.Auch können andere Klassen nicht von Strukturen abgeleitet werden.

Listing 9.22 struct3.cs

using System;

class ConsoleApp{public struct Point{public int x;public int y;

public Point(int x, int y){this.x = x;this.y = y;}

public override string ToString(){return(string.Format("x: {0}, y: {1}", x, y));}}

static void Main(){Point p = new Point(15, 9);

Console.WriteLine(p);

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

x: 15, y: 9

Page 192: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

192 ____________________________________________________ 9.4 Aufzählungen

9.4 Aufzählungen

Aufzählungen oder auch Enumerations sind immer dann nützlich, wenn eineVariable nur eine Auswahl von verschiedenen Status annehmen können soll. Eshandelt sich also um eine Art Zustandsbeschreibung. Strukturen werden mit demSchlüsselwort enum eingeleitet. Innerhalb des folgenden Blocks werden diemöglichen Werte Komma-separiert notiert. Der Zugriff auf diese Elemente erfolgtspäter über den Namen der Aufzählung, gefolgt vom gewünschten Elementnamen.Intern arbeiten Aufzählungen soweit nicht explizit anders angegeben auf Basiseines int-Wertes, der fortlaufend beginnend bei 0 für jedes Element vergeben wird.

9.4.1 Standard-Aufzählungen

Das folgende Beispiel zeigt eine Aufzählung, die über drei verschiedene Statusverfügt. Es soll das Startverhalten eines Windows-Dienstes beschrieben werden. Eskommen hierfür nur drei mögliche Werte in Frage. Über eine switch-Abfrage wirdder Status in Klartext umgewandelt und ausgegeben.

Listing 9.23 enum1.cs

using System;

class ConsoleApp{public enum ServiceStartup{Disabled,Automatic,Manual}

static void Main(){ServiceStartup start = ServiceStartup.Automatic;

string s = "";

switch(start){

case ServiceStartup.Disabled :s = "Deaktiviert";break;

case ServiceStartup.Automatic :s = "Automatisch";

Enumerations

Page 193: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

9 Erweiterte Datentypen ________________________________________________193

break;

case ServiceStartup.Manual :s = "Manuell";break;

}

Console.WriteLine("Startverhalten: " + s);

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Startverhalten: Automatisch

Es ist auch möglich, die zu verwendenden Elementwerte explizit anzugeben. Hierzuwird der gewünschte Wert hinter dem Elementnamen notiert. Wird dennachfolgenden Elementen kein Wert zugewiesen, werden diese fortlaufend ab demangegebenem Wert angenommen. Das folgende Beispiel visualisiert diesenVorgang. Für Disabled wird der Wert 5 angenommen, das nachfolgende ElementAutomatic müsste somit den Wert 6 erhalten. Der tatsächlich gesetzte Wert wirdüber eine doppelte Typenumwandlung zunächst in int und dann in stringermittelt.

Listing 9.24 enum2.cs

using System;

class ConsoleApp{public enum ServiceStartup{Disabled = 5,Automatic,Manual}

static void Main(){ServiceStartup start = ServiceStartup.Automatic;

string s = "";

switch(start){

Page 194: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

194 ____________________________________________________ 9.4 Aufzählungen

case ServiceStartup.Disabled :s = "Deaktiviert";break;

case ServiceStartup.Automatic :s = "Automatisch";break;

case ServiceStartup.Manual :s = "Manuell";break;

}

Console.WriteLine("Startverhalten: " + s);Console.WriteLine(" => " + ((int) start).ToString());

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Startverhalten: Automatisch => 6

9.4.2 Flag-Aufzählungen

Ein weiteres Einsatzgebiet von Aufzählungen sind Flags. Diese werden verwendet,um beispielsweise einer Methode einen Satz an Optionen mitzugeben. Es könnendabei eine beliebige Kombination der verfügbaren Optionen gesetzt sein. Flagsarbeiten intern auf der Basis von einem binären Wert, bei dem jedes Bit eine Optionwiderspiegelt. Dementsprechend müssen die Werte der zur Verfügung stehendenElemente jeweils einem Bit zugeordnet werden. Dies kann entweder über dieentsprechende Dezimalzahl oder die besser lesbare Hexadezimalzahl geschehen.Um mehrere Optionen zu setzen, werden die gewünschten Elemente derAufzählung verodert zugewiesen. Damit dies möglich ist, muss das Attribut „Flags“für die Aufzählung gesetzt sein.

FlagEnumerations

Page 195: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

9 Erweiterte Datentypen ________________________________________________195

Listing 9.25 enumflags1.cs

using System;

class ConsoleApp{[Flags]public enum ShowValues{Value1 = 0x00000001,Value2 = 0x00000002,Value3 = 0x00000004,}

static void Main(){ShowValues show = ShowValues.Value1 | ShowValues.Value3;

if((show & ShowValues.Value1) == ShowValues.Value1){Console.WriteLine("Wert 1 wird ausgegeben");}

if((show & ShowValues.Value2) == ShowValues.Value2){Console.WriteLine("Wert 2 wird ausgegeben");}

if((show & ShowValues.Value3) == ShowValues.Value3){Console.WriteLine("Wert 3 wird ausgegeben");}

Console.ReadLine();}}

Die Ausgabe im Konsolenfenster zeigt, dass tatsächlich nur das erste und dritte Bitgesetzt sind:

Wert 1 wird ausgegebenWert 3 wird ausgegeben

Derartige Konstrukte finden im .NET Framework an vielen Stellen Anwendung,eine konsequente Fortführung dieses Konzeptes in eigenen Programmen ist daherschon aus diesem Grund sinnvoll.

Page 196: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2
Page 197: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

10Konvertierungen

Konvertierung von numerischen Werten

Konvertierung zu string

Konvertierung von Verweistypen

Die Klasse Convert

Page 198: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

198 ___________________________________________________________________

Inhaltsübersicht Kapitel 10

10 Konvertierungen .............................................................................................199

10.1 Konvertierung von numerischen Werten ...........................................................19910.2 Konvertierung zu string .....................................................................................20110.3 Konvertierung von Verweistypen ......................................................................20410.4 Die Klasse Convert ............................................................................................209

Page 199: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

___________________________________________________________________ 199

10 Konvertierungen

Um Daten von einem Datentyp in einen anderen umzuwandeln, ist eineKonvertierung der Datentypen notwendig. Dieser Vorgang wird im Englischen alstype casting bezeichnet. Prinzipiell unterscheidet C# zwischen impliziten undexpliziten Konvertierungen. Implizite Konvertierungen werden durch einfacheZuweisung der Variablen unterschiedlichen Typs vorgenommen. Hierbei kann derZieldatentyp die Quelle vollständig abbilden, sodass keinerlei Datenverluste durchdie Konvertierung auftreten können. Sofern eine Implementierung einer implizitenKonvertierung vorliegt, wird diese vom Compiler akzeptiert und immer zu einemgültigen Ergebnis führen. Anders sieht es bei der expliziten Konvertierung aus. Hiermuss ausdrücklich eine Konvertierung notiert werden. Auch wenn der Compilerdiese prinzipiell akzeptiert, kann sie später fehlschlagen. Die expliziteKonvertierung erfordert die Notation des gewünschten Ziel-Datentyps in rundenKlammern. Es ergibt sich das folgende Schema:

NeueVariable = (NeuerDatentyp) AlteVariable;

Eigentlich implizit mögliche Konvertierungen können immer auch explizit nachdiesem Schema vorgenommen werden.

10.1 Konvertierung von numerischen Werten

Die Grundlagen der Konvertierung von numerischen Werten wurde bereits zuBeginn des Kapitels kurz beschrieben. Je nach Ziel- und Quelldatentyp steht eineimplizite oder eine explizite Konvertierung zur Verfügung. Eine impliziteKonvertierung ist immer in größere Datentypen möglich, da hier keineDatenverluste auftreten können. Ist der Zieldatentyp hingegen kleiner als derQuelldatentyp, ist eine explizite Konvertierung erforderlich.Die beiden folgenden Beispiele demonstrieren noch einmal das Vorgehen. DerDatentyp int ist größer als short und daher ist eine Konvertierung von short zuint implizit möglich. Andersherum ist eine Konvertierung von int zu short nurexplizit möglich.

Page 200: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

200 ______________________________ 10.1 Konvertierung von numerischen Werten

Listing 10.1 convert1.cs

using System;

class ConsoleApp{static void Main(){short n1 = 15;int n2;

n2 = n1;

Console.WriteLine(n2.ToString());

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

15

Listing 10.2 convert2.cs

using System;

class ConsoleApp{static void Main(){int n1 = 15;short n2;

n2 = (short) n1;

Console.WriteLine(n2.ToString());

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

15

Die Tabelle zeigt, welche Datentypen implizit und somit sicher in welche anderenDatentypen konvertiert werden können.

ImpliziteKonvertierung

ExpliziteKonvertierung

Page 201: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

10 Konvertierungen ____________________________________________________201

Tabelle 10.1 Implizite Konvertierungen von numerischen Werten

Quelldatentyp C# Alias Mögliche Zieldatentypen

Byte byte Char, UInt16, Int16, UInt32, Int32, UInt64, Int64, Single,Double, Decimal, Object

SByte sbyte Int16, Int32, Int64, Single, Double, Decimal, Object

Int16 short Int32, Int64, Single, Double, Decimal, Object

UInt16 ushort UInt32, Int32, UInt64, Int64, Single, Double, Decimal,Object

Char char UInt16, UInt32, Int32, UInt64, Int64, Single, Double,Decimal, Object

Int32 int Int64, Single, Double, Decimal, Object

UInt32 uint Int64, Single, Double, Decimal, Object

Int64 long Single, Double, Decimal, Object

UInt64 ulong Single, Double, Decimal, Object

Single float Double, Object

Double double Object

Decimal Decimal Object

10.2 Konvertierung zu string

Die Mutter aller Objekte, der Datentyp object, implementiert eine MethodeToString. Da sich alle anderen Objekte von diesem Datentyp ableiten,implementiert jedes Objekt diese Methode. Wird beim Ableiten die Methodeüberschrieben, kann ein sinnvoller Wert ausgegeben werden. Ist dies nicht der Fall,so wird lediglich der Name des Datentyps ausgegeben.Die Konvertierung einer numerischen Variable zur Ausgabe als string wurdebereits in den vergangenen Beispielen verwendet. Diese ist hier notwendig, um denWert mit Hilfe der Methode Write in das Konsolenfenster auszugeben.

Listing 10.3 convertstring1.cs

using System;

class ConsoleApp{static void Main(){int n = 514044;string s;

s = n.ToString();

Console.WriteLine(n);

ToString

Page 202: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

202 ___________________________________________ 10.2 Konvertierung zu string

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

514044

Versucht man die Methode mit einem Objekt zu verwenden, das diese nicht explizitüberschreibt, so wird lediglich der Datentyp-Name des Objekts ausgegeben. Dasfolgende Beispiel zeigt die Verwendung einer Struktur Point, die einen Punkt imKoordinatensystem mit Hilfe zweier int-Werte x und y repräsentieren soll.

Listing 10.4 convertstring2.cs

using System;

class ConsoleApp{public struct Point{public int x;public int y;

public Point(int x, int y){this.x = x;this.y = y;}}

static void Main(){Point p = new Point(15, 9);

Console.WriteLine(p);

Console.ReadLine();}}

Die Ausgabe im Konsolenfenster zeigt nicht das gewünschte Ergebnis, denn dieInformation über den Objektnamen ist wenig aussagekräftig.

ConsoleApp+Point

Page 203: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

10 Konvertierungen ____________________________________________________203

Wird die Methode ToString jedoch überschrieben und mit einer sinnvollenImplementierung versehen, ist das Ergebnis gleich viel ansehnlicher. Es wird einformatierter string zurückgegeben, der den Inhalt der beiden Mitgliedsvariablen xund y enthält.

Listing 10.5 convertstring3.cs

using System;

class ConsoleApp{public struct Point{public int x;public int y;

public Point(int x, int y){this.x = x;this.y = y;}

public override string ToString(){return(string.Format("x: {0}, y: {1}", x, y));}}

static void Main(){Point p = new Point(15, 9);

Console.WriteLine(p);

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

x: 15, y: 9

ToStringüberladen

Page 204: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

204 ____________________________________ 10.3 Konvertierung von Verweistypen

10.3 Konvertierung von Verweistypen

Die Konvertierung von Verweistypen funktioniert ähnlich wie bei den zuvorbeschriebenen numerischen Wertetypen. Die Konvertierung erfolgt nach demgleichen Schema:

NeueVariable = (NeuerDatentyp) AlteVariable;

Bei Verweistypen wird allerdings nicht der numerische Inhalt der Variable zuGrunde gelegt, sondern die Erbhierarchie der jeweiligen Klasse. Die Vererbung vonKlassen wird unter der Überschrift „Klassen & objektorientierte Programmierung –Teil II“ weiter unten ausführlich erklärt. Das folgende Beispiel verwendet die dorterläuterten Techniken.

Listing 10.6 converref1.cs

using System;

class BasisKlasse{public virtual string Test(){return("BasisKlasse.Test");}}

class ErbKlasse : BasisKlasse{public override string Test(){return("ErbKlasse.Test");}

public string Test2(){return("ErbKlasse.Test2");}}

class ConsoleApp{static void Main(){ErbKlasse Erb = new ErbKlasse();Console.WriteLine(Erb.Test());Console.WriteLine(Erb.Test2());

Page 205: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

10 Konvertierungen ____________________________________________________205

BasisKlasse Basis = (BasisKlasse) Erb;Console.WriteLine(Basis.Test());

// Würde zu einem Fehler führen:// Console.WriteLine(Basis.Test2());

ErbKlasse Erb2 = (ErbKlasse) Basis;Console.WriteLine(Erb2.Test2());

Console.ReadLine();}}

Was passiert hier? Es existiert eine Basisklasse mit einer Implementierung derMethode Test. Eine zweite Klasse wird von der ersten abgeleitet und überschreibtdie Methode Test. Zudem stellt diese Klasse eine weitere Methode mit dem NamenTest2 zur Verfügung.Im Aufruf der Klassen wird die abgeleitete Klasse instanziiert. Es erfolgt der Aufrufder beiden enthaltenen Methoden Test und Test2. Anschließend erfolgt eineexplizite Konvertierung in die Basisklasse. Diese ist möglich, da eine Vererbungimmer eine „ist ein(e)“-Beziehung darstellt; ErbKlasse „ist ein(e)“ BasisKlasse.Es erfolgt erneut der Aufruf der Methode Test. Der Aufruf führt allerdings nichtzur BasisKlasse, sondern zur abgeleiteten Klasse. Dies ist richtig, denn es handeltsich ja ursprünglich um die Instanz der ErbKlasse, auch wenn die Sicht auf dieseInstanz nun über die BasisKlasse erfolgt. Dies wird deutlich, sofern man versucht,die Methode Test2 aufzurufen. Diese ist in der BasisKlasse nicht implementiertund daher würde Aufruf zu einem Fehler führen. Da die ursprüngliche Instanz vomTyp ErbKlasse ist, ist auch eine Rückwärtskonvertierung vom Typ BasisKlassein den Typ ErbKlasse möglich. Der Aufruf der Methode Test2 beweist, dass dieseerfolgreich war. Die Ausgabe im Konsolenfenster zeigt das Ergebnis des Beispiels:

ErbKlasse.TestErbKlasse.Test2ErbKlasse.TestErbKlasse.Test2

Dass eine explizite Konvertierung unsicher ist, zeigt das Beispiel recht deutlich. DieKonvertierung von BasisKlasse zu ErbKlasse ist möglich. Doch was wäre, wennman wie im folgenden Beispiel versuchen würde, eine Instanz der BasisKlasse inden Typ ErbKlasse zu konvertieren?

Page 206: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

206 ____________________________________ 10.3 Konvertierung von Verweistypen

Listing 10.7 convertref2.cs

// Klassen-Implementation entspricht dem// vorangegangenen Beispiel

...

ErbKlasse Erb = new ErbKlasse();Console.WriteLine(Erb.Test());Console.WriteLine(Erb.Test2());

BasisKlasse Basis = new BasisKlasse();Console.WriteLine(Basis.Test());

ErbKlasse Erb2 = (ErbKlasse) Basis;Console.WriteLine(Erb2.Test2());

...

Abbildung 10.1 Die Konvertierung ist fehlgeschlagen

Page 207: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

10 Konvertierungen ____________________________________________________207

Der Compiler akzeptiert die Konvertierung, da eine Konvertierung von BasisKlassezu ErbKlasse theoretisch möglich ist. Wie die Abbildung zeigt, wird allerdings eineAusnahme erzeugt, denn praktisch ist die Konvertierung in diesem Fall nichtmöglich.Um einer solchen Ausnahme vorzubeugen, bietet C# Typenoperatoren an. Diesewurden bereits im Kapitel „Operatoren“ vorgestellt und sollen an dieser Stelle nurkurz angerissen werden.

Der Typenoperator is

Mit is lässt sich überprüfen, ob ein Objekt einem bestimmten Datentyp entsprichtbeziehungsweise in diesen konvertiert werden kann. Hierzu wird links von is dasObjekt und rechts der Datentyp notiert. Die Rückgabe ist ein boolescher Wert, derbestimmt, ob die Konvertierung möglich ist oder nicht. Das folgende Schemaveranschaulicht die Anwendung:

if(Objekt is Datentyp)...

Im folgenden Beispiel wird eine ErbKlasse instanziiert und diese anschließend inBasisKlasse konvertiert. Mit Hilfe des Operators is wird nun geprüft, ob eineRückkonvertierung möglich ist. Analog wird für eine neue Instanz derBasisKlasse verfahren.

Listing 10.8 convertref3.cs

// Klassen-Implementation entspricht dem// vorangegangenen Beispiel

...

ErbKlasse Erb = new ErbKlasse();BasisKlasse Basis1 = (BasisKlasse) Erb;

if(Basis1 is ErbKlasse)Console.WriteLine("Basis1 unterstützt ErbKlasse");elseConsole.WriteLine("Basis1 unterstützt ErbKlasse nicht");

BasisKlasse Basis2 = new BasisKlasse();

Page 208: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

208 ____________________________________ 10.3 Konvertierung von Verweistypen

if(Basis2 is ErbKlasse)Console.WriteLine("Basis2 unterstützt ErbKlasse");elseConsole.WriteLine("Basis2 unterstützt ErbKlasse nicht");

...

Die Ausgabe im Konsolenfenster zeigt, dass das Objekt Basis1 in den TypErbKlasse konvertiert werden kann, bei Basis2 ist diese Konvertierung hingegennicht möglich.

Basis1 unterstützt ErbKlasseBasis2 unterstützt ErbKlasse nicht

Der Typenoperator as

Der Operator as arbeitet ähnlich wie is. Allerdings wird hier nicht nur verglichen,sondern eine Konvertierung auch tatsächlich durchgeführt, sofern diese dennmöglich ist. Ist die Konvertierung nicht möglich, wird null zurückgeliefert. DasSchema sieht wie folgt aus:

NeuesObjekt = Objekt as Datentyp;

Das Ergebnis ließe sich auch auf Basis des Operators is realisieren, dann wärenaber mehrere Befehlszeilen notwendig:

if(Objekt is Datentyp)NeuesObjekt = (Datentyp) Objekt;elseNeuesObjekt = null;

Das nachfolgende Beispiel zeigt die Verwendung des Operators as. Es wird wiederversucht, die Objekte vom Typ BasisKlasse in den Typen ErbKlasse zukonvertieren. Die Abfrage erfolgt hier mit Hilfe des Vergleichs mit null.

Listing 10.9 convertref4.cs

// Klassen-Implementation entspricht dem// vorangegangen Beispiel

...

Page 209: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

10 Konvertierungen ____________________________________________________209

ErbKlasse Erb = new ErbKlasse();BasisKlasse Basis1 = (BasisKlasse) Erb;

ErbKlasse Erb2 = Basis1 as ErbKlasse;

if(Erb2 != null)Console.WriteLine("Basis1 unterstützt ErbKlasse");elseConsole.WriteLine("Basis1 unterstützt ErbKlasse nicht");

BasisKlasse Basis2 = new BasisKlasse();ErbKlasse Erb3 = Basis2 as ErbKlasse;

if(Erb3 != null)Console.WriteLine("Basis2 unterstützt ErbKlasse");elseConsole.WriteLine("Basis2 unterstützt ErbKlasse nicht");

...

Die Ausgabe im Konsolenfenster ist analog zum vorhergehenden Beispiel:

Basis1 unterstützt ErbKlasseBasis2 unterstützt ErbKlasse nicht

Der Operator as wird immer dann eingesetzt, wenn auf ein konvertiertes Objektauch zugegriffen werden soll. Soll lediglich die Möglichkeit der Konvertierungüberprüft werden, bietet sich der Operator is an.

10.4 Die Klasse Convert

Die Klasse Convert aus dem Namespace System ermöglicht eine Vielzahl vonexpliziten Konvertierungen zwischen verschiedenen Datentypen. Hier können aucheher ungewöhnliche Konvertierungen wie string zu bool und string zu DateTimevorgenommen werden. Die Tabelle zeigt die allesamt statischen Methoden derKlasse sowie die jeweils möglichen Quelldatentypen.

Page 210: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

210 ______________________________________________ 10.4 Die Klasse Convert

Tabelle 10.2 Die Methoden der Klasse Convert in der Übersicht

Methode Rückgabewert Quelldatentypen

ChangeType object object; ermöglicht eine beliebige Konvertierungeines angegebenen Objektes in einen anderenTyp und arbeitet somit ähnlich wie derTypenoperator as. Ist die Konvertierung nichtmöglich, wird hier allerdings eine Ausnahme vomTyp InvalidCastException geworfen.

ToBase64String string byte[]

ToBoolean bool bool, byte, char, DateTime, Decimal, double,short, int, long, object, sbyte, float, string, ushort,uint, ulong

ToByte byte bool, byte, char, DateTime, Decimal, double,short, int, long, object, sbyte, float, string, ushort,uint, ulong

ToChar char bool, byte, char, DateTime, Decimal, double,short, int, long, object, sbyte, float, string, ushort,uint, ulong

ToDateTime DateTime bool, byte, char, DateTime, Decimal, double,short, int, long, object, sbyte, float, string, ushort,uint, ulong

ToDecimal Decimal bool, byte, char, DateTime, Decimal, double,short, int, long, object, sbyte, float, string, ushort,uint, ulong

ToDouble double bool, byte, char, DateTime, Decimal, double,short, int, long, object, sbyte, float, string, ushort,uint, ulong

ToInt16 short bool, byte, char, DateTime, Decimal, double,short, int, long, object, sbyte, float, string, ushort,uint, ulong

ToInt32 int bool, byte, char, DateTime, Decimal, double,short, int, long, object, sbyte, float, string, ushort,uint, ulong

ToInt64 long bool, byte, char, DateTime, Decimal, double,short, int, long, object, sbyte, float, string, ushort,uint, ulong

ToSByte sbyte bool, byte, char, DateTime, Decimal, double,short, int, long, object, sbyte, float, string, ushort,uint, ulong

ToSingle float bool, byte, char, DateTime, Decimal, double,short, int, long, object, sbyte, float, string, ushort,uint, ulong

Page 211: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

10 Konvertierungen ____________________________________________________211

Methode Rückgabewert Quelldatentypen

ToString string bool, byte, char, DateTime, Decimal, double,short, int, long, object, sbyte, float, string, ushort,uint, ulong

ToUInt16 ushort bool, byte, char, DateTime, Decimal, double,short, int, long, object, sbyte, float, string, ushort,uint, ulong

ToUInt32 uint bool, byte, char, DateTime, Decimal, double,short, int, long, object, sbyte, float, string, ushort,uint, ulong

ToUInt64 ulong bool, byte, char, DateTime, Decimal, double,short, int, long, object, sbyte, float, string, ushort,uint, ulong

ToBoolean

Das folgende Beispiel zeigt die Verwendung der Methode ToBoolean. Es wird eineZeichenkette mit dem Inhalt true übergeben und in einen booleschen Wertumgewandelt. Mögliche Werte für die Umwandlung sind true und false, wobeidie Groß-Kleinschreibung nicht beachtet wird.

Listing 10.10 tobool1.cs

using System;

class ConsoleApp{static void Main(){string s = "true";bool b = Convert.ToBoolean(s);

Console.WriteLine(b.ToString());

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

True

Page 212: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

212 ______________________________________________ 10.4 Die Klasse Convert

ToDateTime

Auch Datumskonvertierungen sind möglich. Im folgenden Beispiel wird eineZeichenkette mit Hilfe der Methode ToDateTime in eine Variable vom TypDateTime konvertiert.

Listing 10.11 todatetime1.cs

using System;

class ConsoleApp{static void Main(){string s = "02.09.2001";DateTime dt = Convert.ToDateTime(s);

Console.WriteLine(dt.ToString("dddd, d. MMMM yyyy"));

Console.ReadLine();}}

Die Ausgabe im Konsolenfenster zeigt deutlich, dass die Umwandlung in dasDatumsformat tatsächlich erfolgreich war, denn wo kommt sonst der Wochentagher?

Sonntag, 2. September 2001

ToInt32

Der Datentyp System.Int32 des .NET Frameworks ist nichts anderes als der vonC# angebotene Datentyp int. Es wird lediglich ein Alias für den schnellen Zugriffangeboten. Das folgende Beispiel zeigt, wie eine Zeichenkette in einen intkonvertiert wird. Besonders Benutzereingaben müssen oft auf diese Weisekonvertiert werden.

Datums-konvertierung

Page 213: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

10 Konvertierungen ____________________________________________________213

Listing 10.12 toint321.cs

using System;

class ConsoleApp{static void Main(){string s = "25";int n = Convert.ToInt32(s);

n = n*2;

Console.WriteLine(n.ToString());

Console.ReadLine();}}

Ausgabe im Konsolenfenster

50

Alternativ lässt sich die Funktionalität auch wie folgt über die statische MethodeParse des int-Objektes abbilden:

Listing 10.13 toint322.cs

using System;

class ConsoleApp{static void Main(){string s = "25";int n = int.Parse(s);

n = n*2;

Console.WriteLine(n.ToString());

Console.ReadLine();}}

Um im Zuge der Konvertierung zu prüfen, ob eine Zeichenkette tatsächlichumgewandelt werden kann, lässt sich folgendes Konstrukt verwenden:

Page 214: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

214 ______________________________________________ 10.4 Die Klasse Convert

Listing 10.14 toint323.cs

using System;

class ConsoleApp{static void TestInt(string s){try{int n = Convert.ToInt32(s);n = n*2;Console.WriteLine(n.ToString() + "");}catch{Console.WriteLine(s + " ist kein numerischer Wert");}}

static void Main(){string s1 = "25";string s2 = "hjkhj";

TestInt(s1);TestInt(s2);

Console.ReadLine();}}

Das Ausnahmebehandlung versucht zunächst die Konvertierung durchzuführen.Schlägt dies fehl, wird eine entsprechende Ausgabe im Konsolenfenster erzeugt:

50hjkhj ist kein numerischer Wert

Eine ausführliche Beschreibung zu Ausnahmen und Ausnahmebehandlungen findenSie im folgenden Kapitel „Fehlerbehandlung“.

Page 215: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

11Fehlerbehandlung

Was ist eine Ausnahme?

Das try..catch..finally-Konstrukt

Die Klasse Exception

Ausnahmen auslösen

Ausnahmen (kontrolliert) weiterreichen

Eigene Ausnahmen definieren

Zusammenfassung

Page 216: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

216 ___________________________________________________________________

Inhaltsübersicht Kapitel 11

11 Fehlerbehandlung ............................................................................................217

11.1 Was ist eine Ausnahme?....................................................................................21711.2 Das try..catch..finally-Konstrukt........................................................................21911.3 Die Klasse Exception.........................................................................................22311.4 Ausnahmen auslösen .........................................................................................22511.5 Ausnahmen (kontrolliert) weiterreichen ............................................................22811.6 Eigene Ausnahmen definieren ...........................................................................23011.7 Zusammenfassung .............................................................................................234

Page 217: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

___________________________________________________________________ 217

11 Fehlerbehandlung

Nahezu jedes Programm ist von Umgebungseinflüssen abhängig. Dies könnengenauso gut Benutzerinteraktionen wie Systemvoraussetzungen oder die Existenzeines bestimmten Verzeichnisses sein. Alle Umgebungseinflüsse haben einesgemeinsam, sie liegen außerhalb des Einflussbereichs der Entwickler. Im Idealfallverhalten sich alle Faktoren wie gewünscht und das Programm kann tadellosabgearbeitet werden. Was aber, wenn einer der Faktoren sich nicht wie erwartetverhält, das temporäre Verzeichnis nicht existiert oder der Benutzer statt einesDatums die Zeichenkette „übermorgen“ eingegeben hat? In diesen Fällen kommt eszu einem Fehler im Programm. Wenn dieser nicht in irgendeiner Form behandeltwird, kann es zu weitgehenden Fehlfunktionen, Abstürzen und anderenunliebsamen Überraschungen kommen. Als Folge sollten alle Umgebungseinflüsseüberprüft werden und im Fehlerfall entweder tolerant oder mit einer geeignetenMaßnahme wie einer Benutzerausgabe reagiert werden. Man nennt diesFehlerbehandlung.Viele Sprachen haben keine oder nur unterentwickelte Mechanismen zurBehandlung von Fehlern. Oft muss der Entwickler selbst Hand anlegen, möglicheFehlerquellen explizit überprüfen und diese mit Rückgabewerten innerhalb derProgrammlogik an die entsprechende Stelle weiterreichen. Dies ist einerseitswiederum fehleranfällig, da man einen Rückgabewert auch einfach ignorieren kann,und andererseits recht mühsam, denn mögliche Fehlerquellen gibt es viele.Das Microsoft .NET Framework und somit alle .NET-Sprachen einschließlich C#haben ein einheitliches System zur Fehlerbehandlung: Ausnahmen (Englisch:Exeptions).

11.1 Was ist eine Ausnahme?

Eine Ausnahme ist im Grunde nichts anderes als ein Objekt mit Eigenschaften undMethoden. Diese erlauben Zugriff auf weitere Informationen, wie die Art und denOrt der Ausnahme. Es gibt dabei ganz unterschiedliche Ausnahme-Objektebeziehungsweise -Typen. Diese leiten sich alle aus der ursprünglichen Klasse„Exception“ ab. Diese Klasse wird also vererbt.

Exceptions

Page 218: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

218 __________________________________________ 11.1 Was ist eine Ausnahme?

Sobald ein Fehler auftritt, wird eine neue Instanz eines passenden Ausnahme-Objektes instanzziert und die Ausnahme geworfen1. Die aktuelleProgrammausführung wird umgehend abgebrochen und die Ausnahme in derHierarchie der Geltungsbereiche hochgereicht. Konkret bedeutet dies, dass eineAusnahme innerhalb einer Methode geworfen wird, aber erst einen Geltungsbereichhöher im Aufruf dieser Methode behandelt wird.Sofern die Ausnahme nicht durch eine eigene Ausnahmebehandlung bearbeitetwird, übernimmt das .NET Framework diese Aufgabe. Bei einem Windows-Programm erscheint beispielsweise eine MessageBox mit weiteren Informationen,bei ASP.NET wird eine entsprechende Fehlermeldung im Browser ausgegeben. Inbeiden Fällen wird die Programmausführung komplett beendet.Das folgende Beispiel zeigt eine oft erzeugte Ausnahme, die Division durch 0.

Listing 11.1 ausnahme1.cs

using System;

class ConsoleApp{static void Main(){int n1 = 1;int n2 = 0;

Console.WriteLine((n1/n2).ToString());

Console.ReadLine();}}

Bei der Ausführung des Beispieles kommt es natürlich zu einem Fehler und eineentsprechende Ausnahme (System.DivideByZeroException) wird geworfen. Dakeine Ausnahmebehandlung vorhanden ist, wird eine standardisierte Fehlermeldungmit weiteren Informationen erzeugt. Die Abbildung zeigt die Fehlermeldung.Sehr viel schöner wäre es natürlich, wenn das Programm nicht beendet und demBenutzer neben der Fehlermeldung weitere Möglichkeiten zum Fortsetzenangeboten würden. Auch könnte man eine Log-Datei erzeugen, eine E-Mail an denAdministrator senden oder Ähnliches. Der Fantasie sind kaum Grenzen gesetzt.Stellt sich also die Frage, wie man eine Ausnahme selbst behandeln kann. Hierkommt das try..catch..finally-Konstrukt zum Einsatz.

1 „Werfen“ klingt ein wenig, als ob die Ausnahme Welpen zur Welt bringen würde. Tatsächlichhat die Formulierung ihren Ursprung aber in der englischen Beschreibung des Vorgangs: [to]throw an exception.

DivideByZeroException

Page 219: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

11 Fehlerbehandlung ___________________________________________________219

Abbildung 11.1 Die Division durch 0 erzeugt eine Ausnahme

11.2 Das try..catch..finally-Konstrukt

Das try..catch..finally-Konstrukt wird zum Erstellen eigener Ausnahmebehand-lungen verwendet. Das Konstrukt besteht aus drei verschiedenen Blöcken. Im erstenBlock try werden die Anweisungen notiert, die möglicherweise zu einem Fehler,also einer Ausnahme führen könnten. Kommt es tatsächlich zu einer Ausnahme,werden der oder die catch-Blöcke ausgeführt. Wenn es keine Probleme gibt, wirddieser Bereich ignoriert. Der dritte, optionale finally-Block wird, soweit vorhanden,in jedem Fall ausgeführt, unabhängig ob eine Ausnahme geworfen wurde odernicht. Dieser Block ist für Aufräumarbeiten gedacht, beispielsweise wenn Sie eineDatei schließen, eine Protokoll-Ausgabe durchführen müssen oder Ähnliches.

Page 220: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

220 _____________________________________ 11.2 Das try..catch..finally-Konstrukt

Versehen wir also das vorangegangene Beispiel mit einer eigenen Ausnahme-behandlung und schauen wir, was passiert.

Listing 11.2 try..catch..finally1.cs

using System;

class ConsoleApp{static void Main(){int n1 = 1;int n2 = 0;

Console.WriteLine("Wen interessiert schon " +"eine Fehlermeldung?");

try{Console.WriteLine((n1/n2).ToString());}catch {}

Console.ReadLine();}}

Zugegeben, dieses Beispiel sollte in Ihrem Programm möglichst nie auftauchen,aber theoretisch ist es durchaus machbar. Im try-Block wird die ungültige Divisiondurchgeführt, was eine Ausnahme zur Folge hat. Aus diesem Grund wird dernachfolgende catch-Block abgearbeitet; da dieser leer ist, wird die Ausnahmeignoriert. Die Ausgabe im Konsolenfenster sieht wie folgt aus.

Wen interessiert schon eine Fehlermeldung?

„Mich“, werden Sie sagen und ich gebe Ihnen Recht. Im Folgenden finden Sie dasBeispiel in einer etwas eleganteren Form.

Listing 11.3 try..catch..finally2.cs

using System;

class ConsoleApp{static void Main(){int n1 = 1;

try..catch

Page 221: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

11 Fehlerbehandlung ___________________________________________________221

int n2 = 0;

try{Console.WriteLine((n1/n2).ToString());Console.WriteLine("Alles roger");}catch(Exception e){Console.WriteLine("Ups, das war keine gute Idee. " +"Die folgende Ausnahme ist aufgetreten: " +e.Message);

}

Console.ReadLine();}}

Wie Sie erkennen können, wird hinter der catch-Anweisung das Ausnahme-Objektquasi als Parameter angegeben. Wie bereits weiter oben beschrieben, lassen sichauch mehrere catch-Blöcke integrieren. Auf diese Weise lässt sich zwischenbestimmten Fehlern differenzieren. Wird eine Ausnahme geworfen, sucht dasProgramm die am besten passende Ausnahmebehandlung. Im Zweifelsfall ist diesimmer die Klasse Exception, da diese die Mutter aller individuellen Ausnahmendarstellt, die von dieser Klasse abgeleitet werden (müssen).Rechnet man mit einem bestimmten Fehler, wird man für diesen in der Regel einenindividuellen catch-Block integrieren. Alle anderen möglichen Ausnahmen werdendurch einen weiteren, allgemeinen Block behandelt. Das folgende Beispiel zeigtdiese Differenzierung.

Listing 11.4 try..catch..finally3.cs

using System;

class ConsoleApp{static void Main(){int n1 = 1;int n2 = 0;

try{Console.WriteLine((n1/n2).ToString());Console.WriteLine("Alles roger");}catch(DivideByZeroException e)

Mehrere catch-Blöcke

Page 222: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

222 _____________________________________ 11.2 Das try..catch..finally-Konstrukt

{Console.WriteLine("Och, Sie sollen doch nicht " +"durch 0 teilen. Das wissen Sie doch...!");

}catch(Exception e){Console.WriteLine("Ups, das war keine gute Idee. " +"Die folgende Ausnahme ist aufgetreten: " +e.Message);

}

Console.ReadLine();}}

Durch die Division durch 0 hebt die Seite die mahnende Hand sehr deutlich. Fallsein anderer Fehler Ursache für die Ausnahme ist, wird lediglich ein allgemeinerText ausgegeben.Zu guter Letzt nun noch ein Beispiel zur Verwendung des finally-Blocks. Dieser istwie beschrieben optional und sollte nur dann verwendet werden, wenn es Sinnergibt. Zerbrechen Sie sich aber bitte nicht den Kopf, ob dies bei den folgendenAusgaben wirklich der Fall ist, schließlich ist dies hier nur die graue Theorie.

Listing 11.5 try..catch..finally4.cs

using System;

class ConsoleApp{static void Main(){int n1 = 1;int n2 = 0;

try{Console.WriteLine((n1/n2).ToString());Console.WriteLine("Alles roger");}catch(DivideByZeroException e){Console.WriteLine("Och, Sie sollen doch nicht " +"durch 0 teilen. Das wissen Sie doch...!");

}catch(Exception e){Console.WriteLine("Ups, das war keine gute Idee. " +

try..catch..finally

Page 223: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

11 Fehlerbehandlung ___________________________________________________223

"Die folgende Ausnahme ist aufgetreten: " +e.Message);

}finally{Console.WriteLine("Ob Fehler oder nicht, ich hoffe, " +"es hat Ihnen Spaß gemacht und dieser Text erscheint");

}

Console.ReadLine();}}

Natürlich möchte ich Ihnen die Ausgabe im Konsolenfenster nicht vorenthalten,obwohl Sie diese vermutlich schon erahnen können. Beachten Sie bitte, dass derzusätzliche Text aus dem finally-Block auch dann erscheinen würde, wenn es zukeiner Ausnahme kommt. Dieser Block wird – soweit vorhanden – immerausgeführt.

Och, Sie sollen doch nicht durch 0 teilen. Das wissen Sie doch...!

Ob Fehler oder nicht, ich hoffe, es hat Ihnen Spaß gemacht und dieserText erscheint

11.3 Die Klasse Exception

Eine Ausnahme oder Exception ist ein Objekt, eine Klasse. In den bisherigenBeispielen wurde bereits die Message Eigenschaft dieser Klasse beschrieben. DieKlasse bietet eine Reihe weiterer Eigenschaften und Methoden an, die zurBehandlung einer Ausnahme nützlich sein können. Wollen Sie beispielsweise einProtokoll einer wichtigen Ausnahme erstellen, sind Ihnen sicherlich alleverfügbaren Informationen herzlich willkommen. Es folgt eine Beschreibung derhierfür relevanten Mitglieder der Klasse.Beachten Sie, dass individuelle Ausnahmen immer von der Klasse Exceptionabgeleitet werden. Sie erben daher die Eigenschaften und Methoden derMutterklasse und unterstützen diese dementsprechend. Davon abgesehen könnendiese Klassen aber auch eigene zusätzliche Mitglieder anbieten. Beachten Sie hierzugegebenenfalls die jeweilige Dokumentation.

Page 224: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

224 _____________________________________________ 11.3 Die Klasse Exception

Tabelle 11.1 Die Eigenschaften der Klasse Exception im Überblick

Eigenschaft Rückgabewert Beschreibung

HelpLink string Liefert oder setzt eine URL mit einer ausführlichenBeschreibung der Ausnahme, zum Beispiel Verweisauf lokale Hilfedatei oder Ähnliches.

HResult int Liefert oder setzt einen numerischen 32 Bit Wert, derder Ausnahme zur Identifizierung zugewiesen wurde.Diese Eigenschaft kann von abgeleiteten Klassennicht überschrieben werden.

InnerException Exception Sofern der Ausnahme eine andere, behandelteAusnahme vorausgegangen ist, kann einObjektverweis auf die ursprüngliche Ausnahme indieser Eigenschaft abgelegt sein.

Message string Liefert einen Text, der die Ausnahme beschreibt.

Source string Liefert oder setzt die Bezeichnung der Applikationoder des Objektes, in der die Ausnahme aufgetretenist.

StackTrace string Liefert ein StackTrace der Ausnahme, in dem unterUmständen die auslösende Zeile identifiziert werdenkann.

TargetSite MethodBase Liefert – soweit vorhanden – einen Verweis auf dieMethode, die die Ausnahme verursacht hat. Auf dieseWeise lassen sich unter Umständen detailliertereInformationen abfragen.

Tabelle 11.2 Die Methoden der Klasse Exception im Überblick

Methode Rückgabewert Beschreibung

GetBaseException Exception Liefert einen Objektverweis auf die ursprünglicheAusnahme. Sofern die Eigenschaft InnerException aufeine andere Ausnahme verweist, wird dieseAusnahme zurückgeliefert, ansonsten ein Verweis aufdas aktuelle Objekt.

ToString string Liefert eine Zusammenfassung der wichtigstenInformationen der Ausnahme in Form einerZeichenkette.

Das nachfolgende Beispiel gibt zu der bereits bekannten Ausnahme einige Detail-Informationen aus und nutzt hierzu die verschiedenen Eigenschaften der KlasseException.

Page 225: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

11 Fehlerbehandlung ___________________________________________________225

Listing 11.6 exception1.cs

using System;

class ConsoleApp{static void Main(){int n1 = 1;int n2 = 0;

try{Console.WriteLine((n1/n2).ToString());Console.WriteLine("Alles roger");}catch(Exception e){Console.WriteLine("Ups, das war keine gute Idee.\n" +"Die folgende Ausnahme ist aufgetreten:\n\n" +"Meldung: " + e.Message + "\n" +"Quelle: " + e.Source + "\n" +"Stack Trace: " + e.StackTrace);

}

Console.ReadLine();}}

Es fehlt vielleicht noch ein wenig an optischer Eleganz, aber die Informationen ansich können sich durchaus sehen lassen:

Ups, das war keine gute Idee. Die folgende Ausnahme ist aufgetreten:

Meldung: Es wurde versucht, durch null zu teilen.Quelle: atbrbtd5Stack Trace: at ConsoleApp.Main()

11.4 Ausnahmen auslösen

Bisher haben Sie Ausnahmen als etwas kennen gelernt, das vom System auf Grundeines Fehler ausgelöst wird. Sie können aber auch selbst Ausnahmen auslösen. ImRahmen der objektorientierten Programmierung sollten Sie von dieser Möglichkeitauch Gebrauch machen und sie Rückgabewerten oder anderen Informationswegenunbedingt vorziehen. Die (Sprung-) Anweisung zum Werfen einer Ausnahme

Ausnahmen mitInformationenversehen

Page 226: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

226 _____________________________________________ 11.4 Ausnahmen auslösen

wurde bereits in einem früheren Kapitel beschrieben. Es handelt sich um dieAnweisung throw. Als Parameter folgt der Anweisung eine Instanz dergewünschten Ausnahme, zum Beispiel der Klasse Exception.Das folgende Beispiel enthält eine Methode GetString. Diese soll lediglich den alsParameter übergebenen String zurückliefern. Für den Fall, dass dieser auf nullverweist, wird eine entsprechende Ausnahme geworfen. Diese wird von einemtry..catch-Konstrukt behandelt.

Listing 11.7 ausloesen1.cs

using System;

class ConsoleApp{public static string GetString(string s){if(s == null)throw(new ArgumentNullException());return s;}

static void Main(){string s = null;

try{Console.WriteLine(GetString(s));}catch(Exception e){Console.WriteLine("Ups, das war keine gute Idee. " +"Die folgende Ausnahme ist aufgetreten:" +"Meldung: " + e.Message);

}

Console.ReadLine();}}

Die Ausgabe des Beispiels sieht – erwartungsgemäß – wie folgt aus:

Ups, das war keine gute Idee. Die folgende Ausnahme ist aufgetreten:

Meldung: Wert darf nicht Null sein.

throw

Page 227: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

11 Fehlerbehandlung ___________________________________________________227

Die Meldung ist natürlich nicht besonders aussagekräftig, eine angepasste Meldungwäre sehr viel informativer und ist mit einem Handgriff eingebaut. Der Konstruktorder Exception Klasse erlaubt die Angabe einer Zeichenkette, die automatisch derEigenschaft Message zugewiesen wird. Der Konstruktur der hier verwendetenAusnahme ArgumentNullException wurde überschrieben. Hier bleibt derMeldungstext bestehen und wird durch die übergebene Zeichenkette lediglichergänzt. Eine minimale Abänderung des Beispiels führt so zu einem vielübersichtlicheren Ergebnis.

Listing 11.8 ausloesen2.cs

using System;

class ConsoleApp{public static string GetString(string s){if(s == null)throw(new ArgumentNullException("string s der " +"Methode GetString "));

return s;}

static void Main(){string s = null;

try{Console.WriteLine(GetString(s));}catch(Exception e){Console.WriteLine("Ups, das war keine gute Idee. " +"Die folgende Ausnahme ist aufgetreten:" +"Meldung: " + e.Message);

}

Console.ReadLine();}}

Page 228: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

228 _______________________________ 11.5 Ausnahmen (kontrolliert) weiterreichen

Die Ausgabe enthält nun sowohl den ursprünglichen Meldungstext als auch dieindividuelle Ergänzung (im Folgenden kursiv dargestellt).

Ups, das war keine gute Idee. Die folgende Ausnahme ist aufgetreten:

Meldung: Wert darf nicht Null sein. Parametername: string s derMethode GetString

11.5 Ausnahmen (kontrolliert) weiterreichen

Wie weiter oben beschrieben, werden Ausnahmen so lange nach obenweitergereicht, bis sie behandelt werden. In manchen Fällen möchte man eineAusnahme kontrolliert weiterreichen. Dabei wird diese zunächst lokal behandeltund dann neu geworfen. Diese Technik kann beispielsweise verwendet werden,wenn Sie die ursprüngliche Ausnahme mit weiteren Informationen versehen wollen,oder im Gegenteil eine allgemein gefasstere Ausnahme weiterreichen möchten.

Listing 11.9 weiterreichen1.cs

using System;

class ConsoleApp{public static int Divide(int d1, int d2){try{return(d1/d2);}catch(DivideByZeroException e){throw(new DivideByZeroException("Division durch 0, " +"Parameter d2 ist 0", e));

}catch(Exception e){return(0);}}

static void Main(){int d1 = 5;int d2 = 0;

Page 229: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

11 Fehlerbehandlung ___________________________________________________229

try{Console.WriteLine("d1/d2 ergibt: ");Console.WriteLine(Divide(d1, d2));}catch(Exception e){Console.WriteLine("Ups, das war keine gute Idee. " +"Die folgende Ausnahme ist aufgetreten:" +"Meldung: " + e.Message + "");

}

Console.ReadLine();}}

Die Methode Divide enthält eine eigene Fehlerbehandlung. Diese differenziertzwischen einer Division durch 0 und allen anderen Ausnahmen. Sollte eineDivision durch 0 tatsächlich erfolgen (in diesem Beispiel kein Wunder), wird dieAusnahme weitergereicht und vom try..catch-Konstrukt im übergeordnetenGültigkeitsbereich behandelt. Für den Fall, dass eine beliebige andere Ausnahmeauftreten sollte, wird als Ergebnis einfach 0 zurückgeliefert. Die Ausgabe desBeispiels sieht wie folgt aus:

d1/d2 ergibt:Ups, das war keine gute Idee. Die folgende Ausnahme ist aufgetreten:

Meldung: Division durch 0, Parameter d2 ist 0

Alternativ zu einer kontrollierten Weiterreichung von Ausnahmen können Sie sichdie implizite und somit unkontrollierte Weiterreichung auch zu Nutze machen.Dabei verzichten Sie einfach auf eine explizite Fehlerbehandlung in unkritischenMethoden und behandeln eventuell auftretende Ausnahmen einfach imübergeordneten Geltungsbereich. Auf diese Weise sparen Sie sicherlich die eineoder andere Zeile Code. Es empfiehlt sich dennoch eine lokale Behandlung vonAusnahmen, das folgende Beispiel dient daher lediglich der Vollständigkeit.

Listing 11.10 weiterreichen2.cs

using System;

class ConsoleApp{public static int Divide(int d1, int d2){return(d1/d2);}

Ausnahmenautomatischweiterreichen

Page 230: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

230 ______________________________________ 11.6 Eigene Ausnahmen definieren

static void Main(){int d1 = 5;int d2 = 0;

try{Console.WriteLine("d1/d2 ergibt: ");Console.WriteLine(Divide(d1, d2));}catch(Exception e){Console.WriteLine("Ups, das war keine gute Idee. " +"Die folgende Ausnahme ist aufgetreten:" +"Meldung: " + e.Message + "");

}

Console.ReadLine();}}

Natürlich möchte ich Ihnen die Ausgabe dieser Zeilen im Konsolenfenster nichtvorenthalten; sie entsprechen grob denen aus dem vorangegangenen Beispiel.

d1/d2 ergibt:Ups, das war keine gute Idee. Die folgende Ausnahme ist aufgetreten:

Meldung: Es wurde versucht, durch null zu teilen.

11.6 Eigene Ausnahmen definieren

Nachdem Sie bereits einiges über den Umgang mit Ausnahmen gelesen haben,erfahren Sie nun, wie Sie eigene und somit ganz individuelle Ausnahmen definierenkönnen. Diese individuellen Ausnahmen helfen Ihnen bei der genaueren Kontrolleeinzelner Programm-Bereiche. Wenn Sie Ihre Projekte Komponenten-orientiertentwickeln, können Sie mit eigenen Ausnahmen eine flexible Fehlerinformationzwischen den einzelnen Komponenten beziehungsweise Schichten realisieren.Alle Ausnahmen sind im Grunde lediglich eine Klasse und leiten sich direkt oderindirekt von der Klasse Exception ab. Das folgende Beispiel zeigt die Verwen-dung und Auslösung einer selbst definierten Ausnahme.

Page 231: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

11 Fehlerbehandlung ___________________________________________________231

Listing 11.11 eigeneausnahme1.cs

using System;

class ConsoleApp{class GetStringMethodException : Exception {}

public static string GetString(string s){if(s == null)throw(new GetStringMethodException());return s;}

static void Main(){string s = null;

try{Console.WriteLine(GetString(s));}catch(GetStringMethodException e){Console.WriteLine("Der Parameter string s der " +"Methode GetString darf nicht null sein");

}catch(Exception e){Console.WriteLine("Irgendein anderer Fehler ;-)");}

Console.ReadLine();}}

Bereits mit der ersten (fett markierten) Zeile wird eine individuelle Ausnahmedefiniert. Über den Doppelpunkt hinter dem Namen wird deutlich, dass die Klassevon der bestehenden Klasse Exception abgeleitet werden soll und somit derenFunktionalität komplett erbt. Die neue Ausnahme wird im Verlaufe der MethodeGetString instanziiert und geworfen. Die Ausnahmebehandlung fängt dieAusnahme differenziert ab und gibt eine entsprechende Fehlermeldung imKonsolenfenster aus.Natürlich können Sie die Ausnahme auch mit weiteren Anpassungen versehen. Imfolgenden Beispiel wird beispielsweise ein neuer (überladener) Konstruktureingeführt. Dieser erwartetet neben der auszugebenden Message einen zweitenParameter mit dem Inhalt des Hilfe-Links (Eigenschaft HelpLink).

BasisklasseException

Page 232: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

232 ______________________________________ 11.6 Eigene Ausnahmen definieren

Listing 11.12 eigeneausnahme2.cs

using System;

class GetStringMethodException : Exception{public GetStringMethodException() : base() {}public GetStringMethodException(string Message) : base(Message) {}

public GetStringMethodException(string Message, string HelpLink) :base(Message){base.HelpLink = HelpLink;}}

class ConsoleApp{public static string GetString(string s){if(s == null)throw(new GetStringMethodException("Parameter s ist null",

"help.cs"));return s;}

static void Main(){string s = null;

try{Console.WriteLine(GetString(s));}catch(Exception e){Console.WriteLine("Ups, das war keine gute Idee.\n" +"Die folgende Ausnahme ist aufgetreten:\n" +"Meldung: " + e.Message + ".\nWeitere Information " +"finden Sie hier: " + e.HelpLink);

}

Console.ReadLine();}}

Page 233: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

11 Fehlerbehandlung ___________________________________________________233

Auch ganz ausgefallene Erweiterungen sind denkbar. Beispielsweise könnten Sieeine Protokoll-Methode implementieren. Ein Aufruf würde die Protokollierungstarten. Im Folgenden der entsprechend angepasste Rumpf mit der ergänztenMethode LogException:

Listing 11.13 eigeneausnahme3.cs

using System;

class GetStringMethodException : Exception{public GetStringMethodException() : base() {}public GetStringMethodException(string Message) : base(Message) {}

public GetStringMethodException(string Message, string HelpLink) :base(Message){base.HelpLink = HelpLink;}

public void LogException(){// An dieser Stelle könnte eine// Protokollierung in eine Datei erfolgen}}

class ConsoleApp{public static string GetString(string s){if(s == null)throw(new GetStringMethodException("Parameter s ist null",

"help.cs"));return s;}

static void Main(){string s = null;

try{Console.WriteLine(GetString(s));}catch(GetStringMethodException e){Console.WriteLine("Ups, das war keine gute Idee.\n" +"Die folgende Ausnahme ist aufgetreten:\n" +

Protokollierung

Page 234: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

234 _______________________________________________ 11.7 Zusammenfassung

"Meldung: " + e.Message + ".\nWeitere Information " +"finden Sie hier: " + e.HelpLink);e.LogException();}catch(Exception e){// ...}

Console.ReadLine();}}

11.7 Zusammenfassung

Ausnahmen sind ein wirksames Mittel für ein übergreifendes und ausgefeiltesFehlermanagement. Machen Sie sich diese Möglichkeiten zu Nutze. Lassen SieRückgabewerte und andere Mechanismen zur Seite und verwenden Sie in Zukunftlieber konsequent Ausnahmen. Ihr Code wird so übersichtlicher und besser, weilweniger fehleranfällig. Denn früher oder später wird jede Ausnahme behandelt.Dies gilt aber nicht für Rückgabewerte, die schon einmal ungewollt untergehenkönnen!

Page 235: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

12Klassen &

objektorientierteProgrammierung – Teil II

Überladungen

Vererbung

Schnittstellen

Benutzerdefinierte Operatoren erstellen

Page 236: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

236 ___________________________________________________________________

Inhaltsübersicht Kapitel 12

12 Klassen & objektorientierte Programmierung – Teil II ...........................237

12.1 Überladungen ....................................................................................................23712.2 Vererbung..........................................................................................................24112.2.1 Einfache Vererbungen .......................................................................................24212.2.2 Überschreiben von Klassen-Mitgliedern ...........................................................24412.2.3 Verbergen von Klassen-Mitgliedern..................................................................24712.2.4 Konstruktoren und die Vererbung .....................................................................24812.2.5 Klassen versiegeln .............................................................................................25212.2.6 Abstrakte Klassen ..............................................................................................25312.3 Schnittstellen .....................................................................................................25612.3.1 Deklaration einer Schnittstelle...........................................................................25612.3.2 Implementierung einer Schnittstelle ..................................................................25712.3.3 Noch ein tierisches Beispiel...............................................................................25712.3.4 Mehrere gleichnamige Schnittstellen-Mitglieder...............................................26112.4 Benutzerdefinierte Operatoren erstellen ............................................................26212.4.1 Arithmetische Operatoren..................................................................................26212.4.2 Vergleichsoperatoren.........................................................................................26612.4.3 Konvertierungsoperatoren .................................................................................270

Page 237: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

___________________________________________________________________ 237

12 Klassen & objektorientierteProgrammierung – Teil II

Zu Beginn des Kapitels haben Sie bereits über einige Grundlagen zurobjektorientierten Programmierung mit Klassen gelesen. Eine Reihe von weiterenTechniken machen die objektorientierte Programmierung aber erst zu dem, was sieist: ein leistungsfähiges System zur Entwicklung komplexer und wiederverwertbarer Programm-Module. Auf den folgenden Seite möchte ich Ihnen dieseweitergehenden Möglichkeiten der objektorientierten Programmierung mit C#vorstellen.

12.1 Überladungen

Das Überladen ist eine effektive Technik, wenn man eine Funktionalität fürverschiedene Parameter-Strukturen implementieren möchte. Sie haben diesesVorgehen bereits in Teil I im Zusammenhang mit der Erstellung von Konstruktorenkennen gelernt. Dieses lässt sich aber auch auf jede andere Methode einer Klasseanwenden. Es werden dabei mehrere Methoden gleichen Namens, aber mitunterschiedlichen und jeweils eindeutigen Parameter-Strukturen erstellt. BeimAufruf der Methode entscheidet die Übergabe der Parameter, welche derImplementierungen tatsächlich aufgerufen wird. In der Regel ähneln sich dieseImplementierungen oder rufen sich sogar gegenseitig auf. Theoretisch sind sie abervollkommen unabhängig voneinander. Es ergibt sich das folgende Schema:

class KlassenName{

public MethodenName(){// Implementation}

public MethodenName(Datentyp Parameter)

Methoden mitdem gleichenNamen

Page 238: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

238 ___________________________________________________ 12.1 Überladungen

{// Implementation}

public MethodenName(Datentyp Parameter, Datentyp Parameter){// Implementation}

}

Erinnern Sie sich noch an das Beispiel der Katze, die gefüttert werden wollte? Imersten Teil dieses Kapitels demonstrierte dieses Beispiel die prinzipielleVerwendung von Methoden. Der Methode Fuettern wurde eine Nahrung sowiedie gewünschte Anzahl übergeben. Ein optimaler Kandidat für eine Überladung,denn die Anzahl könnte man theoretisch auch weglassen und hierfür einfach einenStandardwert wie eine Portion annehmen. Das folgende Beispiel basiert auf demursprünglichen, wurde jedoch dem Thema angepasst.

Listing 12.1 ueberladen1.cs

using System;

class Katze{public enum Nahrung{Thunfisch,Rinderhack,Huehnchen,Trockenfutter}

int _Zufriedenheitsindex;

public int Zufriedenheitsindex{get{return(_Zufriedenheitsindex);}set{_Zufriedenheitsindex = value;}}

Page 239: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

12 Klassen & objektorientierte Programmierung – Teil II ______________________239

public bool Fuettern(Nahrung Futter){return(Fuettern(Futter, 1));}

public bool Fuettern(Nahrung Futter, int Portionen){

switch(Futter){case Nahrung.Thunfisch :case Nahrung.Rinderhack :case Nahrung.Huehnchen :this.Zufriedenheitsindex+=Portionen;return(true);

default:this.Zufriedenheitsindex-=Portionen;return(false);

}

}}

class ConsoleApp{static void Main(){Katze meineKatze = new Katze();meineKatze.Zufriedenheitsindex = 5;

Console.Write("Zufriedenheitsindex vor Fütterung: ");Console.WriteLine(meineKatze.Zufriedenheitsindex.ToString() + "");

if(meineKatze.Fuettern(Katze.Nahrung.Thunfisch, 5))Console.WriteLine("Das hat geschmeckt!");elseConsole.WriteLine("Das war keine gute Idee!");

if(meineKatze.Fuettern(Katze.Nahrung.Trockenfutter))Console.WriteLine("Das hat geschmeckt!");elseConsole.WriteLine("Das war keine gute Idee!");

Console.Write("Zufriedenheitsindex nach Fütterung: ");Console.WriteLine(meineKatze.Zufriedenheitsindex.ToString() + "");

Console.ReadLine();

Page 240: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

240 ___________________________________________________ 12.1 Überladungen

}}

Ausgabe im Konsolenfenster:

Zufriedenheitsindex vor Fütterung: 5Das hat geschmeckt!Das war keine gute Idee!Zufriedenheitsindex nach Fütterung: 9

Die Methode Fuettern wurde doppelt implementiert, einmal mit zwei und einmalmit nur einem Parameter. Ruft man letztgenannte Methode auf, ruft diese wiederumdie andere mit einem angenommenen Standard-Wert für den zweiten Parameter auf.Das Beispiel ist sehr typisch für die Verwendung von Überladungen. Es gibt aberauch ganz andere Einsatzmöglichkeiten, bei denen sich die Parameter völligunterscheiden. Im folgenden Beispiel wird eine Methode Add zur Addierung zweierWerte verwendet. Es können dabei ganz unterschiedliche Werte übergeben werden:int, Decimal und auch string. Im Fall der Zeichenkette wird versucht, diese ineinen numerischen Wert umzuwandeln, mit dem dann gerechnet werden kann.

Listing 12.2 ueberladen2.cs

using System;

class Test{public static int Add(int n1, int n2){return(n1+n2);}

public static Decimal Add(Decimal n1, Decimal n2){return(n1+n2);}

public static int Add(string s1, string s2){int n1 = Int32.Parse(s1);int n2 = Int32.Parse(s2);return(Add(n1, n2));}}

class ConsoleApp{static void Main()

GleicheMethoden fürunterschiedlicheDatentypen

Page 241: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

12 Klassen & objektorientierte Programmierung – Teil II ______________________241

{Console.WriteLine(Test.Add("25", "16").ToString());

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

41

Wie Sie sehen, können überladene Methoden durchaus auch andere Rückgabewerteerhalten. Im Beispiel existieren insgesamt drei Implementierungen der MethodeAdd, die jeweils über Parameter des gleichen Datentyps verfügen. Bei Übergabevon Zeichenketten wie im Beispiel wird eine Umwandlung vorgenommen und dannwieder die Methode zur Addition von int-Werten aufgerufen. Im Beispiel mag diesübertrieben wirken, gewöhnt man sich jedoch an diese Wiederverwendung, kanndiese bei komplexeren Methoden viel Zeit und Tipparbeit sparen und reduziert dieFehleranfälligkeit.

12.2 Vererbung

Der Themenkomplex Vererbung ist gleichwohl wichtig, interessant und komplex.Es ist ein Grundprinzip der objektorientierten Programmierung, bestehende Klassenzu beerben. Bei diesem Vorgang werden die Mitglieder einer Klasse wieEigenschaften und Methoden sowie deren Implementierung übernommen. Diegeerbte oder auch abgeleitete Klasse besitzt also automatisch deren Funktionalitätund kann diese erweitern und modifizieren.Bei der Vererbung entsteht eine „ist ein(e)“-Beziehung von der Erbklasse zurBasisklasse. Jede geerbte Klasse „ist ein(e)“ Basisklasse. Man kann zudem einerVariable vom Typ der Basisklasse in jedem Fall die Erbklasse zuweisen. DieseMöglichkeit nennt man Polymorphie. Andersherum ist nicht jede Basisklasse einerVariable vom Typ der Erbklasse zuweisbar, denn von einer Basisklasse können jaganz unterschiedlich Erbklassen mit jeweils unterschiedlichen Implementierungenabgeleitet werden. Beachten Sie, dass eine Klasse immer nur von genau eineranderen Basisklasse abgeleitet werden kann.

Basisklasse undErbklasse

Page 242: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

242 ______________________________________________________ 12.2 Vererbung

Ein tierisch gutes Beispiel

Abbildung 12.1 Eine Katze „ist ein“ Tier „ist ein“ object

Die Vererbung lässt sich mit dem Ihnen bereits wohlbekannten Beispiel der Katzehervorragend veranschaulichen. Eine Katze ist ein Tier und hat entsprechendeEigenschaften und Methoden, die für jedes Tier existieren. Insofern erbt die Katzediese vom Tier. Auch ein Hund wäre ein Tier und somit von dieser Klasseabgeleitet. Nach den Regel von C# ist zudem jedes Objekt von der Mutter allerObjekte mit dem treffenden Namen object abgeleitet. Ein Tier ist also direkt oderindirekt auch wieder ein object. Verallgemeinerung ist also die Basis derVererbung von Klassen. Die Abbildung zeigt die Abhängigkeit.

12.2.1 Einfache Vererbungen

Vererbungen werden auf Basis der kompletten Klassen durchgeführt, nicht etwa aufTeilen dieser. Aus diesem Grund erfolgt die Notation bereits bei der Benennung derKlasse. Der Name der Basisklasse wird mit einem Doppelpunkt getrennt hinter demNamen der neuen Erbklasse notiert. Es ergibt sich hierfür folgendes Schema:

Page 243: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

12 Klassen & objektorientierte Programmierung – Teil II ______________________243

class ErbklassenName : BasisklassenName{// Implementierung der abgeleiteten Klassen}

Das nachfolgende Beispiel realisiert die aufgestellte Erb-Abhängigkeit zwischenKatze und Tier. Es existiert eine Klasse Tier mit der Eigenschaft Name. Jedes Tiersollte einen Namen tragen. Die Klasse Katze leitet sich von der Klasse Tier ab undunterstützt zusätzlich zu deren Funktionalität eine neue Eigenschaft Fellfarbe, dieuns über selbige Auskunft geben soll.

Listing 12.3 einfachevererbung1.cs

using System;

class Tier{string _Name;

public string Name{get{return(_Name);}set{_Name = value;}}}

class Katze : Tier{string _Fellfarbe;

public string Fellfarbe{get{return(_Fellfarbe);}set{_Fellfarbe = value;}}}

Page 244: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

244 ______________________________________________________ 12.2 Vererbung

class ConsoleApp{static void Main(){Katze meineKatze = new Katze();

meineKatze.Name = "Filou";meineKatze.Fellfarbe = "rot";

Console.WriteLine("Meine Katze heißt " + meineKatze.Name +" und hat die Fellfarbe \"" + meineKatze.Fellfarbe + "\".");

Console.ReadLine();}}

Die Verwendung der Klasse Katze zeigt, dass diese sowohl über die eigeneEigenschaft Fellfarbe als auch über die geerbte Eigenschaft Name verfügt. BeideEigenschaften werden im Konsolenfenster ausgegeben:

Meine Katze heißt Filou und hat die Fellfarbe "rot".

12.2.2 Überschreiben von Klassen-Mitgliedern

Wie bereits beschrieben, lassen sich im Zuge der Vererbung auch Modifikationenvornehmen. Hierzu wird das jeweilige Mitglied der Klasse überschrieben und neuimplementiert. Die Basisklasse muss dies für das Mitglied explizit erlauben undhierfür mit dem Modifikator virtual versehen. Die neue Implementierung in derabgeleiteten Klasse verwendet den Modifikator override zur Kennzeichnung derÜberschreibung.Das Beispiel zeigt die beiden Klassen Tier und Katze. Die Klasse Tierimplementiert eine Methode Fuettern, die den Zufriedenheitsindex des Tiereserhöht. Die Katze soll zudem schnurren, wenn sie gefüttert wird. Die Methode wirddaher überschrieben und die neue boolesche Eigenschaft Schnurrt gesetzt.

Listing 12.4 ueberschreiben1.cs

using System;

class Tier{int _Zufriedenheitsindex;

Page 245: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

12 Klassen & objektorientierte Programmierung – Teil II ______________________245

public int Zufriedenheitsindex{get{return(_Zufriedenheitsindex);}set{_Zufriedenheitsindex = value;}}

virtual public void Fuettern(string Nahrung){Zufriedenheitsindex += 1;}}

class Katze : Tier{bool _Schnurrt;

public bool Schnurrt{get{return(_Schnurrt);}}

override public void Fuettern(string Nahrung){_Schnurrt = true;Zufriedenheitsindex += 1;}}

class ConsoleApp{static void Main(){Katze meineKatze = new Katze();

meineKatze.Fuettern("Thunfisch");

if(meineKatze.Schnurrt)Console.WriteLine("Meine Katze schnurrt :-)");else

Page 246: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

246 ______________________________________________________ 12.2 Vererbung

Console.WriteLine("Meine Katze schnurrt nicht :-(");

Console.ReadLine();}}

Die Katze ist sichtlich zufrieden:

Meine Katze schnurrt :-)

Das Beispiel funktioniert so weit, hat jedoch einen Schönheitsfehler. Dieursprüngliche Funktionalität der Methode Fuettern, also das Hochsetzen desZufriedenheitsindex, wurde in der abgeleiteten Klasse noch einmal implementiert.Was aber, wenn diese Funktionalität wesentlich komplexer als im gezeigtenBeispiel wäre? Es widerspricht der Regel der objektorientierten Programmierung,Code nicht doppelt zu halten und vor allem auch bei Änderungen nicht doppeltpflegen zu müssen. Abhilfe schafft hier das Schlüsselwort base mit dem analog zuthis der Zugriff auf die Basisklasse möglich ist. Auf diese Weise lässt sichinnerhalb der neuen Methode die alte aufrufen. Das Beispiel wurde dahingehendgeändert; im Folgenden nur der entsprechende Ausschnitt der abgeleiteten KlasseKatze:

Listing 12.5 ueberschreiben2.cs

...

override public void Fuettern(string Nahrung){_Schnurrt = true;base.Fuettern(Nahrung);}

...

An der Ausgabe im Konsolenfenster hat sich natürlich nichts geändert, die Katzeschnurrt weiterhin zufrieden:

Meine Katze schnurrt :-)

Basisklasseaufrufen

Page 247: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

12 Klassen & objektorientierte Programmierung – Teil II ______________________247

12.2.3 Verbergen von Klassen-Mitgliedern

Die Überschreibung von Mitgliedern funktioniert so lange, wie diese in derBasisklasse explizit mit dem Modifikator virtual dafür freigegeben wurde. Wasaber, wenn ein Klassenmitglied nicht freigegeben wurde und Sie die Klasse nichtanpassen können, weil diese beispielsweise von einem Dritt-Hersteller stammt? Indiesem Fall können Sie die ursprüngliche Methode verbergen und durch eine neueersetzen. Es wird hierzu das Schlüsselwort new verwendet.Das folgende Beispiel wurde fast unverändert aus dem vorangegangenen Abschnittübernommen. Allerdings fehlt der ursprünglichen Methode Fuettern derModifikator virtual. Aus diesem Grund musste die neue Methode mit demModifikator new versehen werden. Die zusätzliche Angabe von override ist nichtnotwendig.

Listing 12.6 verbergen1.cs

using System;

class Tier{int _Zufriedenheitsindex;

public int Zufriedenheitsindex{get{return(_Zufriedenheitsindex);}set{_Zufriedenheitsindex = value;}}

public void Fuettern(string Nahrung){Zufriedenheitsindex += 1;}}

class Katze : Tier{bool _Schnurrt;

public bool Schnurrt{get{

new

Page 248: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

248 ______________________________________________________ 12.2 Vererbung

return(_Schnurrt);}}

new public void Fuettern(string Nahrung){_Schnurrt = true;base.Fuettern(Nahrung);}}

class ConsoleApp{static void Main(){Katze meineKatze = new Katze();

meineKatze.Fuettern("Thunfisch");

if(meineKatze.Schnurrt)Console.WriteLine("Meine Katze schnurrt :-)");elseConsole.WriteLine("Meine Katze schnurrt nicht :-(");

Console.ReadLine();}}

Die Ausgabe im Konsolenfenster ist natürlich identisch mit den vorherigen.Obwohl die Methode neu implementiert wurde, ist der Zugriff auf die ursprünglicheMethode der Basisklasse möglich. Ganz wie beim Überschreiben wird auch hier dasSchlüsselwort base verwendet.

12.2.4 Konstruktoren und die Vererbung

Wenn Sie davon ausgegangen sind, dass auch Konstruktoren vererbt werden, dannhaben Sie sich leider getäuscht: sie werden es nicht. Ich lasse das folgende Beispieleinfach einmal für mich sprechen:

Listing 12.7 konstruktoren1.cs

using System;

class Tier{string _Name;

Page 249: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

12 Klassen & objektorientierte Programmierung – Teil II ______________________249

public Tier(string Name){this.Name = Name;}

public string Name{get{return(_Name);}set{_Name = value;}}}

class Katze : Tier{string _Fellfarbe;

public string Fellfarbe{get{return(_Fellfarbe);}set{_Fellfarbe = value;}}}

class ConsoleApp{static void Main(){Katze meineKatze = new Katze("Filou");

meineKatze.Fellfarbe = "rot";

Page 250: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

250 ______________________________________________________ 12.2 Vererbung

Console.WriteLine("Meine Katze heißt " + meineKatze.Name +" und hat die Fellfarbe \"" + meineKatze.Fellfarbe + "\".");

Console.ReadLine();}}

Sie kennen das Beispiel bereits aus den vorherigen Abschnitten, es wurde hierlediglich ein Konstruktor in der Basisklasse eingefügt, über den sich dieEigenschaft Name einfach initialisieren lässt. Eigentlich sollte man annehmen, dassdies nun auch mit der abgeleiteten Klasse Katze möglich ist, denn schließlichwurde ja auch die Eigenschaft geerbt. Die Abbildung belehrt eines Besseren.

Abbildung 12.2 Konstruktoren werden augenscheinlich nicht vererbt

Wenn also Konstruktoren nicht vererbt werden, müssen sie neu implementiertwerden. Das ist im Grunde nur logisch, denn es sollen ja auch die lokalenMitglieder der Klasse initialisiert werden. Damit auch die Basisklasse initialisiertwerden kann, steht erneut das Schlüsselwort base zur Verfügung. Dieses wird wieeine Methode mit den Parametern des Konstruktors aufgerufen und wie folgtnotiert:

class Erbklasse: Basisklasse{

public Erbklasse : base(){// Initialisierung}

public Erbklasse(Datentyp Parameter) : base(Parameter)

base()

Page 251: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

12 Klassen & objektorientierte Programmierung – Teil II ______________________251

{// Initialisierung}

...

}

Die lokale Initialisierung ist optional, es kann auch nur der jeweilige Konstruktorder Basisklasse aufgerufen werden. Natürlich möchte ich Ihnen nicht einangepasstes Beispiel vorenthalten. Jetzt können Sie tatsächlich den Namen derKatze im Konstruktor übergeben.

Listing 12.8 konstruktoren2.cs

using System;

class Tier{string _Name;

public Tier(string Name){this.Name = Name;}

public string Name{get{return(_Name);}set{_Name = value;}}}

class Katze : Tier{string _Fellfarbe;

public Katze(string Name) : base(Name) {}

public string Fellfarbe{get{

Page 252: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

252 ______________________________________________________ 12.2 Vererbung

return(_Fellfarbe);}set{_Fellfarbe = value;}}}

class ConsoleApp{static void Main(){Katze meineKatze = new Katze("Filou");

meineKatze.Fellfarbe = "rot";

Console.WriteLine("Meine Katze heißt " + meineKatze.Name +" und hat die Fellfarbe \"" + meineKatze.Fellfarbe + "\".");

Console.ReadLine();}}

Im Beispiel wurde keine lokale Initialisierung vorgenommen. Der Übersicht halberwurden daher die geschweiften Klammern direkt hinter dem Konstruktor notiert.Die Ausgabe im Konsolenfenster sieht jetzt schon wesentlich besser aus:

Meine Katze heißt Filou und hat die Fellfarbe "rot".

12.2.5 Klassen versiegeln

Angenommen, Sie entwickeln eine Komponente und möchten unbedingtverhindern, dass andere Entwickler Klassen von Ihrer Komponente ableiten. Mitden bisher vorgestellten Möglichkeiten lässt sich dies nicht verhindern, und auchwenn Sie Mitglieder nicht explizit zum Überschreiben freigeben, verfügen Sie mitdem Verbergen der ursprünglichen Mitglieder über eine alternative Möglichkeit.Mit Hilfe des Modifikators sealed können Sie eine Klasse komplett versiegeln undsomit jeglichen Ableitungsversuch im Keim ersticken.Natürlich darf zur Demonstration mal wieder meine Katze herhalten. Im bekanntenBeispiel wurde die Klasse Tier versiegelt, indem lediglich der Modifikator sealedvor dem Klassennamen notiert wurde.

Page 253: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

12 Klassen & objektorientierte Programmierung – Teil II ______________________253

Listing 12.9 versiegelt1.cs

sealed class Tier{

...

Wie die Abbildung zeigt, hat die Versiegelung den gewünschten Effekt. EineVererbung auf Basis der Klasse Tier ist nicht mehr möglich, die Klasse istgeschützt.Beachten Sie bitte, dass Vererbungsmodifikatoren wie abstract und virtual ineiner versiegelten Klasse keinen Sinn ergeben und daher vom Compiler angemosertwerden. Ein sehr bekanntes Beispiel für eine versiegelte Klasse ist übrigens derDatentyp string – schade eigentlich.

Abbildung 12.3 Von einer versiegelten Klasse kann nicht abgeleitet werden.

12.2.6 Abstrakte Klassen

Abstrakte Klassen sind Klassen, die nicht instanziiert, sondern nur abgeleitetwerden können. Abstrakte Klassen enthalten jedoch reguläre Deklarationen fürMitglieder wie Eigenschaften und Methoden und auch entsprechendeFunktionalität. Man verwendet eine abstrakte Klasse zur Verallgemeinerung undzur Zusammenfassung, um so eine gemeinsame Grundlage für verschiedeneabgeleitete Klassen zu bieten. Diese Klassenart wird mit dem Modifikatorabstract notiert:

sealed

Page 254: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

254 ______________________________________________________ 12.2 Vererbung

abstract class Klassenname{...}

Ein prädestinierter Kandidat für solch eine abstrakte Klasse ist die bereitsverwendete Basisklasse Tier. Haben Sie schon einmal ein Tier gesehen? Bestimmtnicht, denn es ist ja nur ein Oberbegriff, eine Verallgemeinerung. Es laufen keineTier-Instanzen in unseren Wäldern herum!

Listing 12.10 abstrakt1.cs

using System;

sealed class Tier{int _Zufriedenheitsindex;

public int Zufriedenheitsindex{get{return(_Zufriedenheitsindex);}set{_Zufriedenheitsindex = value;}}

public void Fuettern(string Nahrung){Zufriedenheitsindex += 1;}}

class Katze : Tier{

...

Sie können auch innerhalb einer abstrakten Klasse einzelne Mitglieder mit demModifikator abstract versehen. In diesem Fall wird lediglich das Grundgerüst desMitglieds deklariert. Die abgeleitete Klasse ist auf diese Weise gezwungen, dasabstrakte Mitglied zu ersetzen und somit zu implementieren.

abstract

Definition einesallgemeinenTieres

Page 255: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

12 Klassen & objektorientierte Programmierung – Teil II ______________________255

Listing 12.11 abstrakt2.cs

using System;

abstract class Tier{abstract public void Fuettern(string Nahrung);}

class Katze : Tier{bool _Schnurrt;

public bool Schnurrt{get{return(_Schnurrt);}}

override public void Fuettern(string Nahrung){_Schnurrt = true;}}

class ConsoleApp{static void Main(){Katze meineKatze = new Katze();

meineKatze.Fuettern("Thunfisch");

if(meineKatze.Schnurrt)Console.WriteLine("Meine Katze schnurrt :-)");elseConsole.WriteLine("Meine Katze schnurrt nicht :-(");

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Meine Katze schnurrt :-)

Page 256: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

256 ___________________________________________________ 12.3 Schnittstellen

Die Methode Fuettern wurde abstrakt in der Basisklasse Tier deklariert und mussdaher von der abgeleiteten Klasse Katze explizit implementiert werden.Anderenfalls kommt es zu einem Compiler-Fehler.

12.3 Schnittstellen

Schnittstellen sind abstrakten Klassen sehr ähnlich. Auch sie implementierenkeinerlei Funktionalität, sondern stellen lediglich den Rahmen für sie dar. Auchwenn die Notation einer Vererbung entspricht, so spricht man doch vomUnterstützen oder auch Implementieren einer Schnittstelle. Dies ist unabhängig vonder Vererbung zu sehen und kann auch parallel zu einer solchen verwendet werden.Die Unterstützung mehrerer Schnittstellen ist ebenfalls ohne weiteres möglich.

12.3.1 Deklaration einer Schnittstelle

Schnittstellen werden mit dem Schlüsselwort interface eingeleitet. Der weitereAufbau entspricht ansonsten aber weitgehend einer regulären Klasse.

interface Schnittstellenname{// Deklaration der Schnittstellen-Mitglieder}

In Schnittstellen können keine Variablen oder Felder deklariert werden. AndereMitglieder wie Eigenschaften, Methoden und Ereignisse sind aber möglich. Diesewerden allerdings nicht öffentlich deklariert (also mit dem Modifikator public),vielmehr wird auf die Angabe eines Zugriffsmodifikators völlig verzichtet.

Microsoft empfiehlt, den Namen einer Schnittstelle immer mit einem großen I wieInterface beginnen zu lassen. Auf diese Weise sieht man auf den ersten Blick, ob essich um eine Klasse oder eine Schnittstelle handelt.Die Deklaration von Eigenschaften innerhalb von Schnittstellen bringt eine kleineBesonderheit mit sich. Statt der Implementierung in geschweiften Klammern wirdeinfach ein Semikolon notiert. Natürlich ist es auch hier möglich, nur eine derbeiden Zugriffsmöglichkeiten get oder set zu implementieren.

interface

Namensgebung

Page 257: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

12 Klassen & objektorientierte Programmierung – Teil II ______________________257

Datentyp Eigenschaftsname{get;set;}

12.3.2 Implementierung einer Schnittstelle

Die Unterstützung einer Schnittstelle wird analog zur Vererbung vorgenommen.

class Klassenname : Schnittstellenname{// ...}

Sollen weitere Schnittstellen unterstützt oder von einer Klasse abgeleitet werden,notiert man die Namen mit Kommata separiert.

class Klassenname : Basisklasse, Schnittstelle1, Schnittstelle2{// ...}

Die Mitglieder einer unterstützten Schnittstelle müssen immer öffentlichimplementiert werden, da ansonsten ein Zugriff von außen nicht möglich wäre.

Durch die Möglichkeit, parallel zu erben und mehrere Schnittstellen zuunterstützen, kann es sehr leicht zu Namenskonflikten kommen. Aus diesem Grundmuss beim Zugriff auf die Mitglieder einer unterstützten Schnittstelle zuvor immereine explizite Konvertierung stattfinden. Ein direkter Zugriff auf die Schnittstellen-Mitglieder über die Instanz ist nicht möglich.

Schnittstelle Schnittstellen-Variable =(Schnittstelle) Klassen-Variable;

12.3.3 Noch ein tierisches Beispiel

Ein Beispiel liefert natürlich wieder einmal die Katzenwelt. Tiere sind dieBasisklasse und Katzen leiten sich von dieser ab. Aber es gibt ganz unterschiedlicheKatzen. Die einen leben wild und die anderen beim Menschen im Haus. Wieder

MehrereSchnittstellenunterstützen

Page 258: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

258 ___________________________________________________ 12.3 Schnittstellen

andere leben zwar beim Menschen im Haus, sind aber dennoch wild und genießendie Freiheit der Natur tagsüber. Die Klasse ist also weiterhin die Katze, die sich vonder Klasse Tier ableitet. Über verschiedene Schnittstellen kann nun definiertwerden, ob es sich um ein Haustier oder ein wildes Tier handelt. So ergibt sichbeispielsweise die Hauskatze.Im konkreten Fall existiert die bereits bekannte abstrakte Klasse Tier. Zudem wirdeine Schnittstelle IHaustier angeboten, die Eigenschaften wie Haart undStubenrein deklariert. Die zwei Klassen Hauskatze und Haushund werdenjeweils von der Klasse Tier abgeleitet und unterstützen die genannte Schnittstelle.Auf diese Weise ist ein einheitlicher Zugriff auf die Methoden der Schnittstellemöglich, unabhängig davon, ob es sich um einen Hund oder eine Katze handelt.

Listing 12.12 schnittstellen1.cs

using System;

abstract class Tier{abstract public void Fuettern(string Nahrung);}

interface IHaustier{bool Haart{get;}

bool Stubenrein{get;}}

class Hauskatze : Tier, IHaustier{bool _Schnurrt;bool _Haart = true;bool _Stubenrein = true;

public bool Schnurrt{get{return(_Schnurrt);}}

SchnittstelleHaustier

Page 259: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

12 Klassen & objektorientierte Programmierung – Teil II ______________________259

public bool Haart{get{return(_Haart);}}

public bool Stubenrein{get{return(_Stubenrein);}}

override public void Fuettern(string Nahrung){_Schnurrt = true;}}

class Haushund : Tier, IHaustier{bool _Bellt;bool _Haart = false;bool _Stubenrein = false;

bool Bellt{get{return(_Bellt);}}

public bool Haart{get{return(_Haart);}}

public bool Stubenrein{get{

Page 260: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

260 ___________________________________________________ 12.3 Schnittstellen

return(_Stubenrein);}}

override public void Fuettern(string Nahrung){_Bellt = false;}}

class ConsoleApp{static void Main(){Hauskatze meineKatze = new Hauskatze();Haushund meinHund = new Haushund();

IHaustier Haustier1 = (IHaustier) meineKatze;IHaustier Haustier2 = (IHaustier) meinHund;

if(Haustier1.Haart)Console.WriteLine("Haustier1 haart");elseConsole.WriteLine("Haustier1 haart nicht");

if(Haustier2.Haart)Console.WriteLine("Haustier2 haart");elseConsole.WriteLine("Haustier2 haart nicht");

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Haustier1 haartHaustier2 haart nicht

Streng gesehen müsste die Klasse Hauskatze natürlich von einer Klasse Katzeabgeleitet werden und analog zum vorliegenden Beispiel die Schnittstelle Haustierunterstützen – aus Übersichtsgründen habe ich hierauf jedoch verzichtet.

Page 261: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

12 Klassen & objektorientierte Programmierung – Teil II ______________________261

12.3.4 Mehrere gleichnamige Schnittstellen-Mitglieder

Weiter oben habe ich bereits angedeutet, dass Objekte explizit konvertiert werdenmüssen, damit auf Schnittstellen-Mitglieder zugegriffen werden kann. AlsBegründung habe ich mögliche Namenskonflikte genannt. Doch lassen sichüberhaupt gleichnamige Schnittstellen-Mitglieder implementieren? Woher soll derCompiler wissen, welche Implementierung zu welcher Schnittstelle gehört? Dieexplizite Schnittstellen-Implementierung weiß diese Fragen zu beantworten.Hierbei wird einfach der Name der zugehörigen Schnittstelle vor dem Namen desMitglieds notiert.Das nachfolgende Beispiel zeigt die Schnittstellen ITest1 und ITest2. Beidedeklarieren eine Methode Test und werden gemeinsam von einer KlasseTestKlasse unterstützt. Damit kein Namenskonflikt auftritt, wird der Name derSchnittstelle vor der Implementierung der jeweiligen Methode Test notiert.

Listing 12.13 schnittstellen2.cs

using System;

interface ITest1{string Test();}

interface ITest2{string Test();}

class TestKlasse : ITest1, ITest2{public string Name;

public TestKlasse(string Name){this.Name = Name;}

string ITest1.Test(){return(string.Format("Test für ITest1, Instanz: {0}", this.Name));}

string ITest2.Test(){return(string.Format("Test für ITest2, Instanz: {0}", this.Name));

ExpliziteImplementierung

Page 262: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

262 ______________________________ 12.4 Benutzerdefinierte Operatoren erstellen

}}

class ConsoleApp{static void Main(){TestKlasse t = new TestKlasse("MeinName");

ITest1 t1 = (ITest1) t;ITest2 t2 = (ITest2) t;

Console.WriteLine(t1.Test());Console.WriteLine(t2.Test());

Console.ReadLine();}}

Die Ausgabe im Konsolenfenster zeigt, dass jeweils die Implementierung derrichtigen Schnittstelle aufgerufen wurde:

Test für ITest1, Instanz: MeinNameTest für ITest2, Instanz: MeinName

12.4 Benutzerdefinierte Operatoren erstellen

Sie können mit C# wirklich fast alles machen. Ein gutes Beispiel hierfür ist dieMöglichkeit, benutzerdefinierte Operatoren für Klassen zu implementieren. Siekönnen dem Entwickler so beispielsweise die Möglichkeit geben, zwei IhrerKlassen einfach zu addieren.

12.4.1 Arithmetische Operatoren

Die Implementierungen von arithmetischen Operatoren in Ihre Klassen kann Ihnenviel Zeit sparen, wenn Sie mit den möglicherweise ganz unterschiedlichen Werteneiner Klasse „addieren“ möchten. Es lassen sich alle verfügbaren arithmetischenGrundoperatoren überschreiben, insbesondere wichtig sind natürlich dieGrundrechenarten, symbolisiert durch +, -, * und /.Die Implementierung beziehungsweise Überladung eines Operators folgt ähnlichenRegeln wie die reguläre Überladung von Methoden. Natürlich darf auch diesmal einspezieller Modifikator nicht fehlen, der den Namen operator trägt. Als Name der

Grundrechen-arten für Klassen

Page 263: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

12 Klassen & objektorientierte Programmierung – Teil II ______________________263

vermeintlichen Methode wird das Operatorsymbol, also beispielsweise das Zeichen„+“ verwendet. Die beiden Operanden werden als Parameter definiert. DerRückgabewert der Methode ist in der Regel identisch mit der Klasse, auf die sichder Operator bezieht und die diesen implementiert.Zu beachten ist, dass alle benutzerdefinierten Operatoren immer als statischeMethoden implementiert werden müssen. Das ist auch ganz logisch, denn diesebeziehen sich ja nicht auf eine bestimmte Instanz, sondern auf den Datentyp ganzallgemein.Es ergibt sich das folgende Schema:

public static operator Datentyp Operator(Datentyp Parameter,Datentyp Parameter)

Das nachfolgende Beispiel zeigt einen benutzerdefinierten Operator im Einsatz.Gegeben ist die Klasse Point, die einen Punkt im Koordinatensystem repräsentiert.Zwei dieser Punkte werden addiert, wobei jeweils der x- und auch der y-Wertaddiert werden und somit einen neuen Punkt ergeben sollen.

Listing 12.14 arithmetisch1.cs

using System;

class Point{public int x;public int y;

public Point() {}

public Point(int x, int y){this.x = x;this.y = y;}

public override string ToString(){return(string.Format("x: {0}, y: {1}", x, y));}

public static Point operator +(Point p1, Point p2){Point newP = new Point();newP.x = p1.x + p2.x;newP.y = p1.y + p2.y;return(newP);}

Zwei Punkteaddieren

Page 264: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

264 ______________________________ 12.4 Benutzerdefinierte Operatoren erstellen

}

class ConsoleApp{static void Main(){Point Punkt1 = new Point(10, 15);Point Punkt2 = new Point(121, 12);Point Punkt3 = Punkt1 + Punkt2;

Console.WriteLine(Punkt3.ToString());

Console.ReadLine();}}

Die Ausgabe im Konsolenfenster zeigt, dass durch die vermeintliche Addition derbeiden Klassen in Wahrheit sowohl der x- als auch der y-Wert korrekt addiertwurden. Zur Ausgabe wurde übrigens die Methode ToString() überschrieben,sodass die Methode beide Werte x und y formatiert ausgibt. Erinnern Sie sich?

x: 131, y: 27

Im Beispiel sind der linke und rechte Datentyp der Operation identisch. Es gehtaber auch anders. Beispielsweise könnte man annehmen, dass sich eine Additionder Klasse Point mit einem int immer auf den x-Wert bezieht. Das Beispiel wurdehierzu um einen Operator erweitert.

Listing 12.15 arithmetisch2.cs

using System;

class Point{public int x;public int y;

public Point() {}

public Point(int x, int y){this.x = x;this.y = y;}

public override string ToString(){return(string.Format("x: {0}, y: {1}", x, y));

Page 265: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

12 Klassen & objektorientierte Programmierung – Teil II ______________________265

}

public static Point operator +(Point p1, Point p2){Point newP = new Point();newP.x = p1.x + p2.x;newP.y = p1.y + p2.y;return(newP);}

public static Point operator +(Point p, int x){Point newP = new Point();newP.x = p.x + x;newP.y = p.y;return(newP);}}

class ConsoleApp{static void Main(){Point Punkt1 = new Point(10, 15);Point Punkt2 = Punkt1 + 8;

Console.WriteLine(Punkt2.ToString());

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

x: 18, y: 15

So schön die Möglichkeit der Überladung von Operatoren ist, so unangenehm kannman sich bei der Implementierung irren. Im vorangehenden Beispiel wurde eineInstanz der Klasse Point mit einem int-Wert addiert. Doch angenommen, manwürde die Notation umdrehen und die Point-Instanz zu dem Wert 8 addieren.

Point Punkt2 = 8 + Punkt1;

Was passiert dann? Ganz klar, es würde ein Compiler-Fehler gemeldet werden,denn es existiert kein Operator für int + Point. Die Reihenfolge der Parametereines Operators ist also ausschlaggebend für die Richtung der Berechnung. DerHintergrund hierfür ist beispielsweise bei der Subtraktion oder Division deutlich zu

Page 266: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

266 ______________________________ 12.4 Benutzerdefinierte Operatoren erstellen

sehen, denn hier spielt die Reihenfolge ja eine elementare Rolle. Im vorliegendenFall der Addition ist sie jedoch irrelevant. Ein weiterer Operator mit umgedrehtenParametern kann also ungehindert die Berechnung dem anderen Operatorüberlassen. Die Deklaration sieht wie folgt aus:

Listing 12.16 arithmetisch3.cs

// Implementierung analog zu arithmetisch2.cs

...

public static Point operator +(int x, Point p){return(p + x);}

...

12.4.2 Vergleichsoperatoren

Auch Vergleichsoperatoren lassen sich auf einfache Weise überladen. Das Prinzipentspricht dabei den arithmetischen Operatoren, lediglich der Rückgabewert ist hierimmer bool. Wichtig ist, dass die Vergleichsoperatoren immer paarweise auftreten.Wenn Sie also == implementieren müssen Sie auch den Gegenspieler !=aufnehmen. Gleiches gilt für < und > sowie <= und >=.Zwei Instanzen der Klasse Point sollen verglichen werden. Die regulärenOperatoren würden lediglich die Verweise vergleichen und feststellen, dass diesenicht übereinstimmen. Die benutzerdefinierten Vergleichsoperatoren vergleichenhingegen die x- und y-Werte beider Instanzen. Sind diese jeweils identisch, handeltes sich um denselben Punkt.

Listing 12.17 vergleich1.cs

using System;

class Point{public int x;public int y;

public Point() {}

public Point(int x, int y){

== und !=

Page 267: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

12 Klassen & objektorientierte Programmierung – Teil II ______________________267

this.x = x;this.y = y;}

public override string ToString(){return(string.Format("x: {0}, y: {1}", x, y));}

public static bool operator ==(Point p1, Point p2){return(p1.x == p2.x && p1.y == p2.y);}

public static bool operator !=(Point p1, Point p2){return(!(p1 == p2));}

public new bool Equals(Point p){return(this == p);}}

class ConsoleApp{static void Main(){Point Punkt1 = new Point(10, 15);Point Punkt2 = new Point(10, 15);

if(Punkt1 == Punkt2)Console.WriteLine("Punkt1 und Punkt2 sind identisch.");elseConsole.WriteLine("Punkt1 und Punkt2 sind nicht identisch.");

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Punkt1 und Punkt2 sind identisch.

Bei der Implementierung des Vergleichsoperators != habe ich es mir ein wenigeinfach gemacht; dieser negiert einfach das Ergebnis des Operators ==; warum auchnicht? Übrigens: In diesem Zusammenhang habe ich auch die ursprüngliche

Page 268: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

268 ______________________________ 12.4 Benutzerdefinierte Operatoren erstellen

Methode Equals verborgen und durch eine neue Implementierung ersetzt. Dieseprüft nun auch die Werte und nicht die Verweise der beiden Instanzen ab undentspricht somit dem Operator ==.Ich habe schon angedeutet, dass auch andere Vergleichsoperatoren wie größer undkleiner überschrieben werden können. Auch dies lässt sich an Hand der KlassePoint veranschaulichen. Dabei wird jeweils das Ergebnis der Multiplikation von x-und y-Wert verglichen. Der Punkt, der also weiter vom Nullpunkt 0, 0 entfernt ist,ist der größere und umgekehrt. Das nachfolgende Beispiel implementiert dieOperatoren < und > sowie auch <= und >=. Letztere verwenden einfach dasErgebnis der bereits vorhandenen Operatoren und liefern dieses verodert zurück,ganz nach dem Prinzip „größer oder gleich“.

Listing 12.18 vergleich2.cs

using System;

class Point{public int x;public int y;

public Point() {}

public Point(int x, int y){this.x = x;this.y = y;}

public override string ToString(){return(string.Format("x: {0}, y: {1}", x, y));}

public static bool operator ==(Point p1, Point p2){return(p1.x == p2.x && p1.y == p2.y);}

public static bool operator !=(Point p1, Point p2){return(!(p1 == p2));}

public new bool Equals(Point p){return(this == p);}

Vergleiche imÜberblick

Page 269: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

12 Klassen & objektorientierte Programmierung – Teil II ______________________269

public static bool operator <(Point p1, Point p2){return((p1.x * p1.y) < (p2.x * p2.y));}

public static bool operator >(Point p1, Point p2){return((p1.x * p1.y) > (p2.x * p2.y));}

public static bool operator <=(Point p1, Point p2){return(p1 == p2 || p1 < p2);}

public static bool operator >=(Point p1, Point p2){return(p1 == p2 || p1 > p2);}}

class ConsoleApp{static void Main(){Point Punkt1 = new Point(50, 15);Point Punkt2 = new Point(10, 11);

if(Punkt1 >= Punkt2)Console.WriteLine("Punkt1 ist größer gleich Punkt2.");elseConsole.WriteLine("Punkt1 ist nicht größer gleich Punkt2.");

Console.ReadLine();}}

Ausgabe im Konsolenfenster

Punkt1 ist größer gleich Punkt2.

Page 270: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

270 ______________________________ 12.4 Benutzerdefinierte Operatoren erstellen

12.4.3 Konvertierungsoperatoren

Arithmetische Operatoren und Vergleichsoperatoren haben Sie bereits kennengelernt. Der dritte Teil der benutzerdefinierten Operatoren widmet sich derKonvertierung. Auch hier können Sie selbst Hand anlegen.Bereits im Kapitel zur allgemeinen Konvertierung von Datentypen ging ich auf dieUnterschiede zwischen impliziter und expliziter Konvertierung ein. Die impliziteKonvertierung sollte nur dann verwendet werden, wenn eine Rückkonvertierungmöglich und ohne Datenverluste durchführbar ist. Eine explizite Konvertierung istin dieser Hinsicht keinen Beschränkungen unterworfen.Ein Konvertierungsoperator wird wie die anderen mit dem Modifikator operatornotiert. Zuvor muss jedoch angegeben werden, ob dieser implizit (Modifikatorimplicit) oder explizit (explicit) vorgenommen werden soll. Es ergeben sichdie nachfolgenden Schemata:

public static implicit operator Ziel-Datentyp(Quell-Datentyp Variable)

beziehungsweise

public static explicit operator Ziel-Datentyp(Quell-Datentyp Variable)

Implizite Konvertierung

Im nachfolgenden Beispiel wurde die Klasse Point umbenannt in Point2D. DesWeiteren wurde eine neue Klasse Point3D eingeführt. Diese kennt neben x- und y-auch einen z-Wert für die dritte Dimension eines Punktes. Die impliziteKonvertierung findet von Point2D nach Point3D statt. Hier können keineDatenverluste auftreten, da der Wertebereich des Zieldatentyps größer ist. EineVariable vom Typ Point2D kann somit problemlos und ohne Notation einesKonvertierungskonstruktes einer Variablen vom Typ Point3D zugewiesen werden.

Listing 12.19 konvertierung1.cs

using System;

class Point2D{public int x;public int y;

public Point2D() {}

public Point2D(int x, int y)

implizit

explizit

Point2DàPoint3D

Page 271: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

12 Klassen & objektorientierte Programmierung – Teil II ______________________271

{this.x = x;this.y = y;}

public override string ToString(){return(string.Format("x: {0}, y: {1}", x, y));}

public static implicit operator Point3D(Point2D p2d){Point3D p3d = new Point3D(p2d.x, p2d.y, 0);return(p3d);}}

class Point3D{public int x;public int y;public int z;

public Point3D() {}

public Point3D(int x, int y, int z){this.x = x;this.y = y;this.z = z;}

public override string ToString(){return(string.Format("x: {0}, y: {1}, z: {2}", x, y, z));}}

class ConsoleApp{static void Main(){Point2D p2d = new Point2D(50, 15);Point3D p3d = p2d;

Page 272: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

272 ______________________________ 12.4 Benutzerdefinierte Operatoren erstellen

Console.WriteLine(p3d);

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

x: 50, y: 15, z: 0

Explizite Konvertierung

Nachdem Sie einen zweidimensionalen Punkt in einen dreidimensionalenkonvertiert haben, interessiert Sie nun der andere Weg. Natürlich lässt sich Point3Dnicht ohne Datenverlust in Point2D konvertieren, schließlich geht die dritteDimension unwiderruflich verloren. Es ist daher die Verwendung eines explizitenKonvertierungsoperators anzuraten. Das vorangegangene Beispiel wurde dazu wiefolgt erweitert.

Listing 12.20 konvertierung2.cs

// Implementierung wie vorheriges Beispiel...

class Point3D{

public int x;public int y;public int z;

public Point3D() {}

public Point3D(int x, int y, int z){this.x = x;this.y = y;this.z = z;}

public override string ToString(){return(string.Format("x: {0}, y: {1}, z: {2}", x, y, z));}

public static explicit operator Point2D(Point3D p3d)

Point3DàPoint2D

Page 273: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

12 Klassen & objektorientierte Programmierung – Teil II ______________________273

{Point2D p2d = new Point2D(p3d.x, p3d.y);return(p2d);}

}

...

class ConsoleApp{static void Main(){Point3D p3d = new Point3D(50, 15, 8);Point2D p2d = (Point2D) p3d;

Console.WriteLine(p2d);

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

x: 50, y: 15

Page 274: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2
Page 275: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

13Weitergehende

Programmierung

Arbeiten mit Threads

Reflections

Arbeiten mit dem CodeDOM

Page 276: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

276 ___________________________________________________________________

Inhaltsübersicht Kapitel 13

13 Weitergehende Programmierung ..................................................................277

13.1 Arbeiten mit Threads .........................................................................................27713.2 Reflections.........................................................................................................28113.2.1 Eine Eigenschaft dynamisch abfragen ...............................................................28113.2.2 Eine Methode dynamisch aufrufen ....................................................................28213.2.3 Eine Methode mit Parametern dynamisch aufrufen ...........................................28313.2.4 Alle Eigenschaften und Methoden auflisten ......................................................28413.3 Arbeiten mit dem CodeDOM ............................................................................28613.3.1 Ein Programm dynamisch erstellen ...................................................................286

Page 277: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

___________________________________________________________________ 277

13 Weitergehende Programmierung

In diesem Abschnitt sollen weitergehende Programmiertechniken besprochenwerden. Diese entstammen nicht dem Sprachumfang von C#, sondern derKlassenbibliothek des .NET Frameworks. Die Techniken werden nur kurzangerissen. Sollte Sie eines der Themen besonders interessieren, empfehle ich dieLektüre weitergehender Werke oder des .NET Framework SDK von Microsoft, dasmit dem Framework installiert wird.

13.1 Arbeiten mit Threads

Windows ist ein Multithreading Betriebssystem und auch in C# können Sie miteigenen Threads programmieren. Aber was ist eigentlich ein Thread? Normaler-weise kennen Sie Programme als sequenziellen Programmablauf. Die Befehlewerden Zeile für Zeile abgearbeitet. Ein solcher Befehlsablauf ist ein Thread. In derRegel besteht ein Programm aus einem solchen Thread. Sie können aber auchindividuell weitere Threads erstellen. Diese laufen dann parallel. Sie könnenThreads synchronisieren, Daten austauschen und so weiter. Das .NET Frameworkstellt hierzu ein ausgesprochen flexibles Klassensystem im NamespaceSystem.Threading zur Verfügung.Zusätzliche Threads werden verwendet, wenn Sie Aktionen quasi gleichzeitigausführen möchten. Ein Beispiel hierfür ist das so genannte Scrapen von (fremden)Webseiten. Ein solches Beispiel finden Sie im nachfolgenden Listing. Es wird einneuer Thread angelegt, der eine andere Internet-Seite abruft und deren Inhalt ineiner Variable ablegt. Der Basis-Thread gibt Fortschrittsmeldungen aus, solange derzweite Thread nicht beendet ist. Wurde die Seite abgerufen, wird deren Inhalt imKonsolenfenster ausgegeben.

Listing 13.1 thread1.cs

using System;using System.Threading;using System.Net;using System.IO;

Eine Websiteasynchronabrufen

Page 278: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

278 _____________________________________________ 13.1 Arbeiten mit Threads

class FetchWebsite{public string Url;public string ResponseText;

public FetchWebsite(string Url){this.Url = Url;}

public void Fetch(){WebRequest request = WebRequest.Create(Url);WebResponse response = request.GetResponse();StreamReader reader = new

StreamReader(response.GetResponseStream());ResponseText = reader.ReadToEnd();}}

class ConsoleApp{static void Main(){// URL muss ersetzt werden!!string Url = "http://localhost/asp.net/thread1.htm";FetchWebsite FW = new FetchWebsite(Url);

Console.Write("Abfrage von " + FW.Url + " gestartet");

Thread FetchThread = new Thread(new ThreadStart(FW.Fetch));FetchThread.Start();

while(FetchThread.IsAlive){Console.Write(".");Thread.Sleep(100);}

Console.WriteLine("\nAbfrage beendet!\n");Console.WriteLine(FW.ResponseText);

Console.ReadLine();}}

Die Abbildung zeigt deutlich die Ausgabe der Fortschrittsinformation in Form vonPunkten. Sobald die Seite gescrapt wurde, wird diese ausgegeben. Beide Aktionenerfolgen parallel.

Page 279: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

13 Weitergehende Programmierung _______________________________________279

Was passiert genau? Der Thread wird über das Schlüsselwort neu instanziiert.Übergeben wird ein Delegate auf die gewünschte Start-Methode. Diese darf keineParameter enthalten und keinen Rückgabewert liefern (void). Über die MethodeStart wird der neue Thread gestartet. Die while-Schleife wird so langedurchlaufen, wie der Thread aktiv ist. Dies wird über die Eigenschaft IsAliveabgefragt. Innerhalb der Schleife wird pro Aufruf ein Punkt ausgegeben, explizitmit der Flush-Methode an das Konsolenfenster übergeben und der Thread für 100Millisekunden angehalten. Dies ist notwendig, damit der andere Thread Leerlaufzeitzur Abarbeitung erhält. Wird die Schleife verlassen, steht der Inhalt der gescraptenInternet-Seite zur Verfügung und wird ausgegeben. Auf die Methoden zum Scrapensoll hier nicht genauer eingegangen werden.

Abbildung 13.1 Die Ausgabe des Thread-Beispiels im Konsolenfenster

Übersicht

Die Klasse Thread verfügt neben den bereits im Beispiel verwendetenEigenschaften und Methoden natürlich noch über weitere Mitglieder. Die beidenTabellen listen die wichtigsten Eigenschaften und Methoden auf. StatischeMitglieder sind mit einem * gekennzeichnet.

Page 280: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

280 _____________________________________________ 13.1 Arbeiten mit Threads

Tabelle 13.1 Die wichtigsten Eigenschaften der Klasse Thread in der Übersicht

Eigenschaft Rückgabewert Beschreibung

CurrentThread* Thread Liefert den aktuellen Thread, in dem derAufruf erfolgt, als Objekt vom Typ Threadzurück.

IsAlive bool Gibt zurück, ob der Thread gestartet undaktiv ist oder nicht.

IsBackground bool Liefert oder setzt, ob der Thread imHintergrund läuft.

Name string Liefert oder setzt den Namen des Threads.

ThreadPriority ThreadPriority Liefert oder setzt die Priorität des Threads(Enumeration).

ThreadState ThreadState Liefert den Status des Threads(Enumeration).

Tabelle 13.2 Die wichtigsten Methoden der Klasse Thread in der Übersicht

Methode Rückgabewert Beschreibung

AllocateDataSlot* LocalDataStoreSlot Alloziiert einen Slot zum Austausch vonDaten zwischen Threads.

AllocateNamedDataSlot* LocalDataStoreSlot Alloziiert einen Slot mit einem bestimmtenNamen zum Austausch von Daten zwischenThreads.

GetData* object Liefert Daten aus einem übergebenen Slotaus.

GetNamedDataSlot* LocalDataStoreSlot Liefert einen zuvor erstellten Slot mit demübergebenen Namen zurück.

ResetAbort* void Setzt alle eventuell gestarteten Abort-Aufrufe zurück.

SetData* - Setzt Daten in einen übergebenen Slot.

Sleep* - Hält den aktuellen Thread für dieübergebene Anzahl an Millisekunden an.

Abort - Bricht einen Thread komplett ab.

Intrerrupt - Unterbricht einen Thread, wenn dieser dasnächste Mal im Warte- oder Join-Modus ist.

Join - Führt einen Thread mit dem aktuellenzusammen und wartet so, bis dieserbeendet wird.

Resume - Setzt einen zuvor angehaltenen Threadwieder fort.

Start - Startet einen Thread.

Suspend - Hält einen Thread an.

Page 281: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

13 Weitergehende Programmierung _______________________________________281

13.2 Reflections

Über Reflections lassen sich Meta-Daten von Objekten abfragen und manipulieren.Die hierzu verfügbaren Klassen werden im Namespace System.Reflectionzusammengefasst. Auf die einzelnen Objekte soll an dieser Stelle nicht weitereingegangen werden, allerdings möchte ich Ihnen die prinzipiellen Möglichkeitenan Hand einiger Beispiele demonstrieren.

13.2.1 Eine Eigenschaft dynamisch abfragen

Im ersten Beispiel wird der Inhalt der Eigenschaft einer Klasse dynamisch abgefragtund im Konsolenfenster ausgegeben.

Listing 13.2 reflections1.cs

using System;using System.Reflection;

class Test{string _ID;

public string ID{get{return(_ID);}set{_ID = value;}}}

class ConsoleApp{static void Main(){Test test = new Test();test.ID = "hallo welt";

Type t = test.GetType();

PropertyInfo

Page 282: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

282 _____________________________________________________ 13.2 Reflections

PropertyInfo property = t.GetProperty("ID");Console.WriteLine(property.Name + " = " + property.GetValue(test,null).ToString());

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

ID = hallo welt

13.2.2 Eine Methode dynamisch aufrufen

Auch der Zugriff auf Methoden ist möglich. Im zweiten Beispiel wird die Methodeeiner Klasse aufgerufen und der Rückgabewert im Konsolenfenster ausgegeben.

Listing 13.3 reflections2.cs

using System;using System.Reflection;

class Test{string _ID;

public string ID{get{return(_ID);}set{_ID = value;}}

public string TestMethode(){return(ID);}}

class ConsoleApp{

MethodInfo

Page 283: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

13 Weitergehende Programmierung _______________________________________283

static void Main(){Test test = new Test();test.ID = "hallo welt";

Type t = test.GetType();

MethodInfo method = t.GetMethod("TestMethode");object retValue = method.Invoke(test, null);

Console.WriteLine("Führe Methode " + method.Name + " aus...");Console.WriteLine("Rückgabewert: " + retValue.ToString());

Console.ReadLine();}}

Ausgabe im Konsolenfenster:

Führe Methode TestMethode aus...Rückgabewert: hallo welt

13.2.3 Eine Methode mit Parametern dynamisch aufrufen

Sofern eine Methode Parameter erfordert, lassen sich diese in Form eines object-Arrays übergeben. Das folgende Beispiel verwendet eine Methode Add zumAddieren von zwei übergebenen int-Werten. Das Ergebnis der Addition wird imKonsolenfenster ausgegeben.

Listing 13.4 reflections3.cs

using System;using System.Reflection;

class Test{public int Add(int n1, int n2){return(n1+n2);}}

class ConsoleApp{

Invoke

Page 284: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

284 _____________________________________________________ 13.2 Reflections

static void Main(){Test test = new Test();

Type t = test.GetType();

MethodInfo method = t.GetMethod("Add");object[] parameters = {154, 55};object retValue = method.Invoke(test, parameters);

Console.WriteLine("Führe Methode " + method.Name + " aus...");Console.WriteLine("Rückgabewert: " + retValue.ToString());

Console.ReadLine();}}

Die Ausgabe im Konsolenfenster zeigt, dass die Addition wirklich durchgeführtwird:

Führe Methode Add aus...Rückgabewert: 209

13.2.4 Alle Eigenschaften und Methoden auflisten

Das vierte Beispiel zum Thema Reflections zeigt die Ausgabe aller Eigenschaftenund Methoden einer Klasse. Im Beispiel wird die Klasse string verwendet, es lässtsich aber alternativ auch jede andere Klasse verwenden. Neben dem Namen derEigenschaften wird auch deren Rückgabewert sowie – wenn möglich – der Inhaltausgegeben. Bei den Methoden werden der Name, der Rückgabewert und einSternchen ausgegeben, sofern es sich um eine statische Methode handelt. Über eineif-Abfrage und eine Variable mit dem Namen der letzten Methode wirdsichergestellt, dass jeder Methodenname nur einmal ausgegeben wird. Ansonstenkönnte dieser durch Überladungen auch mehrfach vorkommen.

Listing 13.5 reflections4.cs

using System;using System.Reflection;

class ConsoleApp{static void Main(){string text = "hallo welt :-)";

Page 285: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

13 Weitergehende Programmierung _______________________________________285

Type t = text.GetType();

Console.WriteLine("Eigenschaften der Klasse " + t.Name + "");

PropertyInfo[] properties = t.GetProperties();foreach (PropertyInfo property in properties){try{Console.Write(property.Name + " (" +property.PropertyType.Name + ")");Console.Write(" = " + property.GetValue(text, null).ToString());}catch{}finally{Console.WriteLine("");}}

Console.WriteLine("\nMethoden der Klasse " + t.Name + "");

MethodInfo[] methods = t.GetMethods();string LastMethod = "";foreach (MethodInfo method in methods){if(LastMethod != method.Name){Console.Write(method.Name + " (" + method.ReturnType.Name + ")");if(method.IsStatic)Console.Write(" *");Console.WriteLine("");LastMethod = method.Name;}}

Console.ReadLine();}}

Die Abbildung zeigt die Ausgabe im Konsolenfenster bei Anwendung des Beispielsauf die Klasse string.

Page 286: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

286 _______________________________________ 13.3 Arbeiten mit dem CodeDOM

Abbildung 13.2 Das Beispiel listet alle Eigenschaften und Methoden einer Klasse auf.

13.3 Arbeiten mit dem CodeDOM

Über das .NET Framework lassen sich auch dynamisch Programme erzeugen.Hierzu stellt das Framework den Namespace System.CodeDom zur Verfügung. Diedort angebotenen Schnittstellen müssen für die jeweilige Programmierspracheindividuell implementiert werden. Für C# liegen diese Implementierungen imNamespace Microsoft.CSharp.

13.3.1 Ein Programm dynamisch erstellen

Im folgenden Beispiel wird dynamisch über ein Objektmodell ein C#-Programmmit einer Klasse und einer Methode erzeugt. Es handelt sich um eine Konsolen-Applikation, die im Verlaufe des Beispiels kompiliert und auf der Festplatteabgelegt wird. Dort kann das Programm anschließend ausgeführt werden. DasBeispiel ist mit Kommentaren versehen, sodass Sie die einzelnen Schritte inVerbindung mit dem .NET Framework SDK gut nachvollziehen können.

Listing 13.6 reflections5.cs

using System;using System.CodeDom;using System.CodeDom.Compiler;using System.IO;using Microsoft.CSharp;

Page 287: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

13 Weitergehende Programmierung _______________________________________287

class ConsoleApp{static void Main(){// Neue Compile Unit erstellenCodeCompileUnit ccu = new CodeCompileUnit();

// Neuen Namespace erstellen und der Unit hinzufügenCodeNamespace cn = new CodeNamespace("pal.ReflectionTest");ccu.Namespaces.Add(cn);

// Namepace "Systems" importierencn.Imports.Add(new CodeNamespaceImport("System"));

// Klasse erstellenCodeTypeDeclaration ctd = new CodeTypeDeclaration("TestClass1");

// Methode erstellenCodeMemberMethod cmm = new CodeMemberMethod();cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;cmm.Name = "Main";

// Variablen für Code deklarierenCodeMethodInvokeExpression cmie;CodeMethodReferenceExpression cmre;

// Code hinzufügencmie = new CodeMethodInvokeExpression();cmre = cmie.Method;cmre.MethodName = "Console.WriteLine";CodeSnippetExpression cse = newCodeSnippetExpression("\"Hallo Welt!\"");cmie.Parameters.Add(cse);cmm.Statements.Add(cmie);

cmie = new CodeMethodInvokeExpression();cmre = cmie.Method;cmre.MethodName = "Console.ReadLine";cmm.Statements.Add(cmie);

// Methode hinzufügenctd.Members.Add(cmm);

// Klasse hinzufügencn.Types.Add(ctd);

// C# CodeProvider initialisierenCSharpCodeProvider cp = new CSharpCodeProvider();

Page 288: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

288 _______________________________________ 13.3 Arbeiten mit dem CodeDOM

// C# Code Compiler erstellenICodeCompiler cc = cp.CreateCompiler();

// Verzeichnis ermittelnstring CurDir = Directory.GetCurrentDirectory();string AssemblyName = CurDir + "\\hallowelt.exe";

// Code compilierenCompilerParameters cparam = new CompilerParameters();cparam.GenerateExecutable = true;cparam.OutputAssembly = AssemblyName;cc.CompileAssemblyFromDom(cparam, ccu);

Console.WriteLine("Die Datei hallowelt.exe wurde erstellt.");

Console.ReadLine();}}

Die Abbildung zeigt die Konsolen-Applikation während der Ausführung auf demClient.

Abbildung 13.3 Es wurde tatsächlich ein funktionierendes Programm dynamisch erstellt.

Page 289: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

Index

@@ 133

AAbort 280Abs 112abstract 64, 67, 253Abstrakte Klassen 253Acos 112Addition 105AllocateDataSlot 280AllocateNamedDataSlot 280Alternierungszeichen 157and 116Anführungszeichen 132Append 150AppendFormat 150, 151Arcuscosinus 112Arcustanges 112Arithmetische Operatoren 262Array 93ArrayList 181, 182Arrays 171

Dynamisch 182Eigenschaften und Methoden 170, 177

Initialisierung und Zugriff 171Mehrdimensionale 174

as 127, 208Asis 112Atan 112Atan2 113Attribute 74Aufzählungen 192Ausnahmen 216, 217

auslösen 225definieren 230weiterreichen 216, 228

BBackslash 132Bedingungen 79Bedingungsoperator 86Betrag 112BinarySearch 180Bitweise Operatoren 118Bool 28break 83, 88, 94, 99byte 28Byte 201

Page 290: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

290 _______________________________________________________________ Index

CC Scharf 13C Sharp 13C# 13C++ 13Capacity 149case 83catch 216, 219Ceiling 113ChangeType 210char 28, 201Chars 136, 149class 43Clear 180CLR 15Collections 181Common Language Runtime 15Compare 138CompareTo 139Compiled 165CompileToAssembly 163Component Update 16Concat 138ConditionalAttribute 75Console 33const 64continue 94, 99Convert 209Copy 138CopyTo 139Cos 113Cosh 113Cosinus 113cs 18csc.exe 18CurrentThread* 280

DDatentypen 28Decimal 28, 201default 84delegate 56

Dequeue 185Destruktor 72Division 105do 92double 28, 201Dynamische Mitglieder 38, 46

EEigenschaften 39

auflisten 284deklarieren 38, 48dynamisch abfragen 281read-only 53write-only 53else 80

Empty 136EndsWith 139, 140Enqueue 185EnsureCapacity 150Enumerator 185Equals 138, 139, 150Ereignisse 39

deklarieren 56Escape 163Escape-Zeichen 132event 56, 64Exception 217, 223Exp 113ExplicitCapture 165Explizite Konvertierung 272Expliziten Konvertierung 199extern 64

FFehlerbehandlung 217fifo 185finally 216, 219first-in-first-out 185Flag-Aufzählungen 194float 28, 201Floor 113for 89

Page 291: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

Index ______________________________________________________________ 291

foreach..in 92Format 138Format Methode 134Formatierungen 134

GGarbage Collection 71, 73get 49GetBaseException 224GetData 280GetGroupNames 164GetGroupNumbers 164GetLength 181GetLowerBound 181GetNamedDataSlot 280GetType 125GetUpperBound 181GetValue 181goto 84, 100Groß-Klein-Schreibung 26GroupNameFromNumber 164GroupNumberFromName 164Gruppierungen 157, 166Gültigkeitsbereich 25

HHallo Welt 35Hashtable 181, 183HelpLink 224HResult 224

IIDictionaryEnumerator 185if 78, 79IgnoreCase 165IgnorePatternWhitespace 165Implizite Konvertierung 199, 270Indexer 26, 172IndexOf 139, 141, 177, 180IndexOfAny 139Initialize 181inline 86

InnerException 224Insert 139, 142, 150Installation 12, 16Int 28, 201Int16 201Intermediate Language 16Intern 138internal 64Intrerrupt 280is 126, 207IsAlive 280IsBackground 280IsFixedSize 180IsMatch 158, 163IsReadOnly 180

JJava 13JIT 16Join 139, 280JScript 14Just-In-Time-Compiler 16

KKlassen 38, 40

abstrakte 253Instanziierung 38, 41versiegeln 252

Klassenprogrammierung 40Kommentare 30Konsolen-Applikationen 33Konstanten 28Konstruktor 67

statisch 71Konstruktoren 236, 248Konvertierung 29

Explizit 272Implizit 270von numerischen Werten 199von Verweistypen 198, 204zu string 198, 201

Page 292: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

292 _______________________________________________________________ Index

Konvertierungsoperatoren 270Kurz-Operatoren 108

LLastIndexOf 139, 181LastIndexOfAny 139last-in-first-out 188Length 137, 150, 180lifo 188Linux 16Log 113Log10 113Logarithmus 113Logische Operatoren 115Logisches 116long 28, 201

MMain 34

Fehlercodes 35Kommandozeilen-Parametern 34

Maskierung 132Matches 159, 160, 163Math 112Max 113MaxCapacity 150Mehrdimensionale Arrays 174Message 224Meta-Daten 281Meta-Zeichen 156Methoden 39

auflisten 284deklarieren 38, 53dynamisch aufrufen 282

Microsoft Intermediate Language 16Microsoft.CSharp 286Min 113Mitglieder 26

überschreiben 244verbergen 247

Modifikatoren 63Modulo 107

Modulus 95MSIL 16Multiline 165Multiplikation 105Multithreading 277

NName 280Namespaces 30Negationsoperator 118new 172None 165Notation 25Notepad 19

Oobject 39, 201Objekt 38, 39

Deklaration 38, 43Terminierung 38, 42

objektorientierte Programmierung 40ObsoleteAttribute 75Operatoren

Arithmetische 262Benutzerdefinierte erstellen 236, 262Binäre 118Konvertierung 270Kurz-Operatoren 108logische 115Negation 118Typen 123Vergleich 115, 266Verknüpfung 116Zuweisung 110

or 116override 64, 67

PPadLeft 139, 142PadRight 139Parameter 26Peek 188

Page 293: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

Index ______________________________________________________________ 293

Pi 114Pop 188Potenz 113Pow 113private 64, 65protected 64public 64, 65Push 188

QQuantifizierungszeichen 157Queue 182, 185

RRank 180ReadLine 33readonly 64Referenzen 157Reflections 75, 123, 281Regex 157

Optionen 164Regular expressions 152Reguläre Ausdrücke 152

Aufbau 153Übersicht 155

Remove 140, 151Replace 140, 143, 151, 161, 163ResetAbort 280Restbetrag 107Resume 280return 35, 55, 101Reverse 178, 181RightToLeft 165Round 113Runden 113

Ssbyte 28, 201Schlüsselwort 25Schnittstellen 256

Deklaration 256gleichnamige Mitglieder 236, 261

Implementierung 257sealed 64, 67, 252Service Releases 16set 49SetData 280SetValue 181SharpDevelop 21short 28, 201Sign 113Sin 113Single 201Singleline 165Sinh 113Sinus 113Sleep 280Sonderzeichen 132Sort 181SortedList 182, 187Source 224Split 140, 144, 162, 164Sqrt 113Stack 182, 188StackTrace 224Standard-Konstruktor 69Standard-Operatoren 105Start 280StartsWiths 140static 47, 64, 66Statische Mitglieder 46string 28, 131, 201StringBuilder 148

Eigenschaften 149Methoden 150

Strukturen 189Substring 140, 145Subtraktion 105Suspend 280switch 78, 82

Zeichenketten 85System 32System.CodeDom 32, 286System.Collection 32, 181

Page 294: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

294 _______________________________________________________________ Index

System.ComponentModel 32System.Configugration 32System.Convert 209System.Data 32System.Diagnostics 32System.DirectoryServices 32System.DivideByZeroException 218System.Drawing 32System.Globalization 32System.IO 32System.Management 32System.Math 112System.Messaging 32System.Net 32System.Reflection 32, 281System.Ressources 32System.Security 32System.ServiceProcess 32System.Text 33System.Text.RegularExpressions 152System.Threading 33, 277System.Timers 33System.Type 123System.Web 33System.Windows.Forms 33

TTan 113Tanges 113Tanh 113TargetSite 224this 62, 190ThreadPriority 280Threads 277ThreadState 280throw 102, 226Tilde 72ToBase64String 210ToBoolean 210, 211ToByte 210ToChar 210ToCharArray 140, 145

ToDateTime 210, 212ToDecimal 210ToDouble 210ToInt16 210ToInt32 210, 212ToInt64 210ToLower 140, 146ToSByt 210ToSingle 210ToString 211, 224ToString() 29, 191, 201ToUInt16 211ToUInt32 211ToUInt64 211ToUpper 140, 146Trim 140, 147

TrimEnd 140, 147TrimStart 140, 147

try 216, 219Typeninformationen 123Typenoperatoren 123, 207typeof 123

ÜÜberladungen 237Überschreiben 236, 244

Uuint 28UInt16 201ulong 28Unescape 164unsafe 65ushort 28

VVariablen 27Verbergen 236, 247Vererbung 241

Konstruktoren 248Vergleichsoperatoren 115, 266Verknüpfungsoperatoren 116

Page 295: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2

Index ______________________________________________________________ 295

versiegeln 252virtual 65, 67Visual Basic.NET 14Visual C++ 14Visual FoxPro.NET 16Visual J++ 15Visual Sourcesafe 6.0c 16Visual Studio.NET 14, 20Vorzeichen 113

WWährung 134WebServiceAttribute 75Wenn..Dann 79while 91Windows 2000 14Windows CE 16

Windows Component Update 16Windows XP 14Write 33WriteLine 33Wurzel 113

Xxor 120

ZZeichengruppen 156Zeichenketten

Eigenschaften 136Methoden 138Operationen 138Zuweisung 131

Zuweisungsoperatoren 110

Page 296: C Sharp Shortcut - Programmieren im .NET-Framework mit der C Sharp Beta 2