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"
|