Triple Eye Industrieel Ingenieur Informatica Algemeen Intranet Derde jaar Netwerken II Labo's C#
Kennismaking met C#

Kennismaking met C#

Inleiding

In dit labo zullen we een speelgoed-bestandssysteempje op poten zetten. Het is vooral de bedoeling kennis te maken met typische C#-aspecten zoals properties, indexers enz. Let hierbij op de gelijkenissen en verschillen met Java en C++. Hou je zoveel mogelijk aan de gebruikelijke C#-stijlconventies, met name i.v.m. naamgeving (hoofdletters, ...).

1. Een bestandsysteem

Maak een nieuw project "BestandSysteem1" (C# console applicatie).

Voeg een klasse Bestand in "Bestand.cs" toe aan het project toe (Add New Item...)

Voorzie deze klasse van:

  • private attributen naam en inhoud (beide van het type string).
  • een publieke constructor met als argumenten naam en inhoud
  • publieke get/set-properties Naam, Inhoud
  • een publieke get-property Grootte, die de grootte van de inhoud geeft.
  • een publieke methode ToString() die de naam teruggeeft, gevolgd door een dubbele punt en de bestandsgrootte.

Om te testen: voeg "Test1.cs" toe aan het project.
Opmerking: je kunt Main() ook in de klasse Bestand onderbrengen, maar een aparte testklasse is netter.

2. Uitbreiding

Voeg een bestand "Map.cs" toe waarin klasse Map gedefinieerd wordt.

Een Map-object kan meerdere bestanden bevatten (een "directory"). Deze worden bijgehouden in een ArrayList.

  • Maak een constructor die een lege bestandslijst maakt.
  • Voorzie een get-property Aantal die het aantal bestanden in de map teruggeeft.
  • Maak een string-indexer die het bestand met een bepaalde naam teruggeeft. Indien de map geen bestand bevat met de gezochte naam, geef dan null terug.
  • Implementeer een methode VoegToe(Bestand b). Indien de map reeds een bestand met dezelfde naam bevat, werp dan een ApplicationException met gepaste boodschap op.
  • Implementeer een methode Verwijder(string naam). Indien het bestand niet in de map voorkomt, werp dan een ApplicationException met gepaste boodschap op.
  • Maak een get-property Grootte die de totale grootte van al zijn bestanden teruggeeft. Extra: probeer de berekening van de totale grootte eens als een procedure te implementeren, waarbij de grootte een uitvoerparameter is.
  • Zorg ervoor dat je de bestanden van een Map kunt overlopen d.m.v. een foreach. Hoertoe moet de klasse de interface IEnumerable implementeren.

Om te testen: excludeer "Test1.cs" uit het project en voeg "Test2.cs" toe.

3. Hierarchisch bestandsysteem

Maak een nieuw project ""BestandSysteem2" (C# console applicatie). Verwijder het bestand "Class1.cs" uit het project. Kopieer d.m.v. Windows-verkenner de bestanden "Bestand.cs", en "Map.cs" naar de projectdirectory en voeg ze toe aan het project. Het is de bedoeling deze bestanden te wijzigen. Bewaar de originele ("BestandSysteem1").

Om het mogelijk te maken dat een directory ook subdirectories kan hebben, zouden we Map kunnen afleiden van Bestand. Directories zouden dan ook een naam en een inhoud hebben.
Nog beter is het om beide af te leiden van een basisklasse ABestand (een abstracte klasse, vandaar de prefix 'A'). Deze basisklasse bevat de (niet abstracte) property Naam, maar definieert bovendien een abstracte property Grootte (read-only) en een abstracte methode void Print(). Deze properties/methodes worden "gespecializeerd" door de afgeleide klassen:

  • Voor de klasse Bestand geeft Grootte de bestandsgrootte terug (een eigen attribuut). De methode Print() zet de naam op het scherm gevolgd door een newline. De klasse heeft ook een eigen attribuut Inhoud.
  • Voor de klasse Map geeft Grootte de som van de groottes van al zijn "kinderen" (en kleinkinderen...) terug. De methode Print() zet de naam van de directory op het scherm gevolgd door een dubbele punt en een newline, en roept daarna de Print-methode op voor al zijn kinderen (recursief). Een Map heeft geen "inhoud".
Om de output wat verzorgder te maken kunnen we inspringen (indenteren) per niveau. Daartoe geven we aan de methode Print() een argument int level mee. Dit argument bepaalt de indentering, bv. drie spaties per niveau. Bij de initiele oproep is level==0; directories roepen Print(level + 1) op voor hun kinderen, enz.
  • Voorzie een statische methode DoIndent(int level) in ABestand die de nodige spaties schrijft.
  • Implementeer de nodige Print() methodes. Bij verstek is level==0!

Testklasse : "Test3.cs".

4. Ouders

Volgens dit systeem kent elke directory zijn "kinderen", maar bestanden en directories kennen hun "ouders" niet. Dit kan opgelost worden door een property Ouder (van het type Map) aan ABestand toe te voegen. Bij constructie van een file/directory is de ouder onbepaald (null). Pas wanneer een file/directory aan een directory wordt toegevoegd wordt zijn ouder bepaald (merk op dat deze dubbele boekhouding potentieel gevaarlijk is en normaalgezien enkel gebruikt wordt om performantieredenen).

  • Voorzie een privaat attribuut ouder en overeenkomstige publieke property Ouder in ABestand.
  • Pas de methode VoegToe() aan in Map. Genereer een exceptie indien het bestand reeds in een map zit (dus een niet-null ouder heeft).
  • Implementeer een property Pad in ABestand die de volledige padnaam teruggeeft van een file/directory, waarbij directories door een schuine streep gescheiden worden. Dit kan eenvoudig recursief opgelost worden.

5. Hashtable

Zoeken naar een bestand op naam in een ArrayList is niet efficiënt. Analoog voor het verwijderen van een bestand. Daarom kun je de ArrayList beter vervangen door een Hashtable.

Doe dit in een nieuw project "BestandSysteem3"


K. Van De Wiele 22/10/2009

Welkom | Hogeschool Gent | INWE | Studentenserver | Docentenserver | Intranet