Übungsaufgaben zu Kapitel 4. Die .NET Klassenbibliothek

4.1 Collections

  1. Enumerator. Implementieren Sie eine einfach verkettete Liste aus Knoten, die jeweils ein char-Property besitzen. Dann erweitern Sie Ihre Liste so, dass man mit Hilfe eines eigenen Enumerators durch Ihre Liste von chars iterieren kann. Implementieren Sie die Liste selbst, d.h. greifen Sie nicht auf die Klassenbibliothek zurück.

  2. Sortierung. Implementieren Sie eine Klasse Vektor, die einen 2 dimensionalen Vektor darstellen soll (z.b: [0,0] oder [10.5, 11]). Dann erweitern sie Ihre Klasse Vektor so, dass bei einer Sortierung eines Vektor-Arrays, der Vektor mit der kleinsten Länge an erster Stelle steht. Die Länge eines Vektors [x, y] bestimmt man wie folgt: Länge = | x*x - y*y |.

  3. Array. Implementieren Sie eine Methode Rotate(Array a), welche ein übergebenes 2 dimensionales Array a um 90° nach links rotiert, ohne dabei ein Array als Zwischenspeicher anzulegen.

    Beispiel:

    1 2 3
    4 5 6
    7 8 9
    3 6 9
    2 5 8
    1 4 7






  4. Stack. Implementieren Sie eine Addiermaschine, welche auf dem Stack-Prinzip basiert. Diese Addiermaschine bietet folgende Befehle an, die mit den jeweiligen ganzzahligen Parametern von der Konsole eingelesen werden:

    Create: Legt eine Stack-Addiermaschine an.

    Put value: Legt einen Wert value am Stack ab.

    Get: Gibt den ersten Wert am Stack auf der Konsole aus.

    Add: Nimmt die zwei ersten Werte vom Stack, addiert diese, und legt das Ergebnis wieder am Stack ab.

    Flush: Entfernt alle Werte vom Stack.


  5. Hashtable. Implementieren Sie eine Klasse TextStatistics, welche eine Methode Hashtable countWords(string text) anbietet, um die Anzahl der auftetenden Wörter in einem Text zu bestimmen. Die Methode countWords liefert ein Objekt vom Typ Hashtable zurück, das die jeweilige Wortstatistik enthält.

4.2 Ein-/Ausgabe

  1. Verzeichnisse und Dateien. Schreiben Sie eine Methode TreeDump(string path, string tabs), welche ausgehend vom Dateipfad path, alle Dateien und Unterverzeichnisse rekursiv auf der Konsole ausgibt. Achten Sie dabei auf eine übersichtliche Formatierung mit Tabulatoren, die sie bereits in tabs als Parameter rekursiv angeben können.

  2. Dateien lesen. Schreiben Sie ein Programm, das den Inhalt einer Textdatei auf der Konsole ausgibt. Der Pfad bzw. der Name der auszugebenden Datei soll als Kommandozeilenparameter eingelesen werden.

  3. Dateien kopieren. Schreiben Sie ein Programm, das eine Datei kopieren kann. Dazu lesen Sie den Pfad der Quelldatei und den Zielpfad als Komandozeilenparameter ein.

  4. Isolierte Speicherbereiche. Legen Sie einen Isolierten Speicherbereich an, auf den nur der aktuell eingeloggte Benutzer Zugriff hat. Schreiben sie einige Daten in diesen Speicherbereich und überprüfen Sie das Ergebnis mit dem StoreAdm-Werkzeug.

  5. Isolierte Speicherbereiche. Diskutieren Sie für welche Anwendungen sich isolierte Speicherbereiche anbieten.

4.3 Threading

  1. Druckaufträge. Simulieren Sie mit Hilfe eines Threads anfallende Druckaufträge zusammen mit ihrer Seitenanzahl. Die Intervalle zwischen den Aufträgen und die Seitenanzahl legen Sie mit Hilfe eines Zufallszahlengenerators fest (bestimmen Sie sinnvolle Grenzen). Verwenden Sie dazu die Klasse System.Random. Wenn ein Druckauftrag anfällt wird dieser in eine Queue eingreiht. Ein zweiter Thread nimmt die Aufträge aus der Queue und gibt sie mit ihrer Seitenanzahl und der Startzeit/Datum auf der Konsole aus.

  2. Druckaufträge Verarbeitung. Nun erweitern Sie Ihre Simulation der Druckaufträge, sodass drei verschiedene Drucker (als Threads implementiert) zur Verfügung stehen und bei anfallenden Druckaufträgen belegt werden können. Die Dauer der Druckerbelegung ergibt sich aus dem Produkt der Seitenanzahl und einer Druckerkonstanten (z.b: 1000ms/Seite), die bestimmt wie lange der jeweilige Drucker für das Drucken einer Seite braucht. Während dieser Druckzeit schläft der jeweilige Drucker. Nach Beendigung eines Druckauftrags schreibt der Drucker ein Druckprotokoll auf die Konsole und überprüft ob neue Aufträge anstehen.

  3. Dining Philisophers. Führen Sie eine Literaturrecherche durch und erläutern Sie das Problem der dining Philisophers. Dann implementieren Sie das "Dining Philosophers Problem" mit Hilfe von Threads und zeigen, wie es zu einer Verklemmung kommen kann.

  4. Dining Philisophers. Lösen Sie das Problem der Philosophen mit Hilfe der Klasse Monitor auf, sodass es zu keiner Verklemmung kommen kann.

4.4 Netzwerkkommunikation

  1. Domainnamen. Versuchen sie mit Hilfe der Klasse Dns alle IP-Adressen des Domainnamens www.microsoft.comauszulesen und auf der Konsole auszugeben.

  2. Netzressourcen. Adressieren sie die Ressource www.dotnet.jku.at/index.html und geben sie deren HTML-Inhalt auf der Konsole aus.

  3. Timeserver. Implementieren Sie einen Server, der bei einer Clientanfrage die lokale Uhrzeit am Host zurückgibt.

  4. Timeserver, quasiparallelle Clientanfrage. Erweitern Sie Ihren TimeServer so, dass mehrere Clients quasiparallel verarbeitet werden können. Verwenden Sie für diese Aufgabe einen Thread, der kontinuierlich auf Clients wartet und diese bedienen kann.

4.5 Reflection

  1. Assembly laden. Schreiben Sie eine Klasse TestReflection und fügen Sie im Editor eine parameterlose öffentliche Methode ( public void TestWithout() ) und eine Methode mit Parametern ( public bool TestWith(string p1) ) in die Klasse ein. Dann übersetzen Sie diese Klasse in ein Assembly und versuchen dieses Assembly mit Hilfe der Klasse Assembly zu laden. Geben Sie relevante Informationen über das Assembly auf der Konsole aus.

  2. Methodensuche. Suchen Sie im Assembly TestReflection nach den beiden Methoden TestWith und TestWithout. Geben Sie alle relevanten Informationen der beiden Methoden auf der Konsole aus.

  3. Objekte dynamisch erzeugen. Laden Sie wieder das Assembly TestReflection und erzeugen Sie ein Objekt des Typs TestReflection.

  4. Methoden ausführen. Rufen Sie die beiden Methoden TestWith und TestWithout mittels Reflection auf.

  5. Reflection.Emit. Diskutieren Sie welche Möglichkeiten Ihnen zur Verfügung stehen wenn Sie den Namensraum System.Reflection.Emit einsetzen.

  6. Typ dynamisch erzeugen. Betrachten Sie, mit Hilfe des ildasm Tools den IL-Code, der für die beiden Methoden TestWith und TestWithout erzeugt wurde. Dann versuchen Sie den Typ, bzw. das ganze Assembly dynamisch mit dem Namensraum Reflection.Emit zu erzeugen.

4.6 Windows.Forms

  1. Vordefinierte Dialoge. Öffnen Sie einen Dialog vom Typ ColorDialog um eine Farbe auszuwählen und deren Color-Wert auszulesen.

  2. Ereignisse. Implementieren Sie ein Formular-Fenster welches 3 Button-Controls enthält, die mit "rot" grün" und "blau" beschriftet sind. Nun verbinden Sie das Ereignis Click mit einer geeigneten EventHandler-Methode, die die Hintergrundfarbe des Formulars nach der jeweiligen Button-Farbe setzt.

  3. UserControls. Implementieren Sie ein benutzerdefiniertes Steuerelement das eine Menge von Werten übernimmt und daraus ein Tortendiagramm zeichnet. Verwenden Sie das BarChartControl in Kapitel 4.6 als Vorlage.

  4. Multiple Document Interface. Implementieren Sie ein Formular-Fenster das einen MDI-Container darstellt und andere MDI-Kindfenster enthalten kann. Erzeugen Sie einen Toolbar für jedes Fenster, der jeweils einen Button zum Öffnen eines neuen MDI-Kindfensters enthält und einen Button zum Schließen des Fensters.

4.7 XML Verarbeitung

  1. Serieller Zugriff auf XML-Daten. Diskutieren Sie die Vor- und Nachteile des seriellen Zugriffs (SAX-Ansatz) auf XML-Daten im Gegensatz zur XML-Datenstruktur (DOM-Ansatz).

  2. Serieller Zugriff auf XML-Daten. Wo liegt der Unterschied zwischen dem in Java XML API (PUSH) implementierten SAX-Ansatz und dem durch XmlReader implementierten (PULL) SAX-Ansatz?

  3. Arbeitszeit speichern. Implementieren Sie eine Klasse Work, die eine Liste von Arbeitszeiten verwalten kann (also Datum des Arbeitstages, Arbeitszeit an diesem Tag und bearbeitete Aufgabe). Dann fügen Sie eine Methode Store(string fileName) ein, welche diese Daten in XML-Form in die angegebene Datei speichern kann.

  4. Arbeitszeit laden. Erweitern sie die Klasse Work, so dass sie eine Methode Load(string fileName) bietet, um die Arbeitszeiten aus einer Datei zu laden.

  5. Arbeitszeit mit SAX-Ansatz summieren. Addieren Sie alle Arbeitsstunden aus einer Datei und geben Sie die Summe auf der Konsole aus. Verwenden Sie dazu den seriellen SAX-Ansatz.

  6. XSL. Erstellen Sie ein XSL-Stylesheet, das die in XML gespeicherte Arbeitszeit in eine HTML-Darstellung transformiert. Verwenden Sie dazu die Klasse XslTransform.