This article has been localized into Dutch by the community.
Namespaces
In een van de eerste hoofdstukken hadden we het kort over namespaces. Je herkent het keyword waarschijnlijk aangezien dit voorkomt in bijna alle C# code, bijna helemaal bovenaan. Een namespace is een manier om een set types (bijvoorbeeld klassen) te groeperen in een groep met een eigen naam. Als Visual Studio een nieuw project voor je genereert maakt hij ook automatisch een standard namespace aan waarin je eerste bestand wordt opgeslagen (Dit is zo als je een Console App maakt, bij andere projecten kan dit anders zijn). Hier zie je een voorbeeld:
using System;
namespace MyProject
{
class Program
{
static void Main(string[] args)
{
// More code below this....
In dit voorbeeld is de namespace MyProject nu een deel van de applicatie. Als je een klasse uit deze namespace buiten de namespace wilt gebruiken zal je de naam van de namespace moeten meegeven als prefix. Dit zie je ook wanneer je bepaalde zaken wilt gebruiken die diep in het .NET framework verborgen zitten:
System.IO.File.ReadAllText("test.txt");
In dit geval gebruiken we de ReadAllText() methode die we vinden in de File klasse die op zijn beurt deel uitmaakt van de System.IO namespace. Het zou veel werk zijn als we telkens zo'n lange naam moeten typen als we een klasse uit een namespace willen gebruiken. C# laat ons echter toe om een volledige namespace te "importeren" in je bestand door gebruik te maken van de using statement. Ook deze zal je misschien reeds herkennen omdat je die bijna altijd helemaal bovenaan je C# bestanden vindt. Als we de File klasse meer dan een keer zouden gebruiken zou het een goed idee zijn om de System.IO namespace te importen, dat doen we als volgt:
using System;
using System.IO;
// More using statements here...
Waarom je namespaces nodig hebt
Als je net begint te programmeren vraag je je misschien af waarom we namespaces nodig hebben. Waarom niet alle klassen in dezelfde namespace plaatsen zodat ze altijd allemaal toegankelijk zijn? Dat kan je doen, maar alleen zolang je aan kleine projecten werkt. Zodra je meer en meer klassen begint toe te voegen is het een goed idee om ze onder te verdelen in verschillende namespaces. Het maakt het makkelijker om je code terug te vinden, zeker als je je bestanden in corresponderende folders plaatst. Het is zelfs zo als je een folder toevoegt aan je project en dan een klasse aanmaakt binnen die folder dat Visual Studio die klasse automatisch in de corresponderende namespace zal plaatsen. Als je dus een folder plaatst in MyProject en je noemt die MyFolder dan zullen klassen die toegevoegd worden aan deze folder automatisch in de MyProject.MyFolder namespace geplaatst worden.
Een mooi voorbeeld van waarom namespaces nodig zijn is het .NET framework zelf. Stel je even voor dat alle klassen binnen het framework in één grote globale namespace zouden zitten, dit zou een grote rotzooi zijn. In plaats daarvan hebben ze deze mooi georganiseerd. System is de hoofd namespace voor de meeste klassen en deze heeft dan sub-namespaces zoals System.IO voor input/output gerelateerde zaken, System.Net voor netwerk gerelateerde zaken en System.Net.Mail voor e-mail gerelateerde zaken.
Naamconflicten met namespaces
Zoals vermeld dienen namespaces ook om je types (meestal klassen) te groeperen, zodat deze binnen hun eigen domein kunnen bestaan. Dit wil ook zeggen dat je klassen kan aanmaken met dezelfde naam als klassen die reeds in je project zitten of zelfs klassen die in het .NET framework zitten. Zo kan je bijvoorbeeld beslissen dat je zelf ook een File klasse nodig hebt. Zoals we gezien hebben in het vorige voorbeeld bestaat er reeds zo'n klasse in de System.IO namespace. Op volgende manier kan je dit aanmaken in je eigen klasse:
using System;
namespace MyProject.IO
{
class File
{
public static void HelloWorld()
{
Console.WriteLine("Hello, world!");
}
}
}
Als je dit nu wilt gebruiken in je project, bijvoorbeeld in je Program.cs hoofdmethode (als je in een Console App werkt zoals ik) kan je de volledige naam gebruiken:
MyProject.IO.File.HelloWorld();
Maar met dank aan het using keyword kan je ook de namespace importeren zoals je met een andere namespace (ingebouwd of zelf gedefinieerd) zou doen. Hier een voorbeeld:
using System;
using MyProject.IO;
namespace MyProject
{
class Program
{
static void Main(string[] args)
{
File.HelloWorld();
}
}
}
Zover werkt alles goed, maar wat als je nu ook de File klasse van de System.IO namespace wil gebruiken? Wel, dit kan voor problemen zorgen, want als je de System.IO namespace ook importeert in je project zal de compiler niet meer weten over welke File klasse je het hebt, die van jezelf of die uit de System.IO namespace. Dit kan je oplossen door maar een de namespaces te importeren (die waarvan je de meeste types gebruikt) en dan de andere aan te spreken door de volledige naam te gebruiken. Je ziet dit hier:
using System;
using System.IO;
namespace MyProject
{
class Program
{
static void Main(string[] args)
{
MyProject.IO.File.HelloWorld();
}
}
}
Het is natuurlijk wat omslachtig om dit elke keer op deze manier te typen, zeker als je klasse wat dieper in de namespace zit. Bijvoorbeeld MyProject.FileStuff.IO.File. Gelukkig heeft C# hier een oplossing voor.
Een alias gebruiken
Om de naam van een namespace in te korten kan je de namespace importeren onder een andere naam door gebruik te maken van een alias. Kijk even hoe we dit doen:
using System;
using System.IO;
using MyIO = MyProject.IO;
namespace MyProject
{
class Program
{
static void Main(string[] args)
{
File.ReadAllText("test.txt");
MyIO.File.HelloWorld();
}
}
}
Kijk even goed naar de derde lijn, waar we de MyProject.IO namespace importeren en deze een kortere naam geven (MyIO). Deze kortere naam kunnen we dan gebruiken als we types van de MyProject.IO namespace willen bereiken. Op dit moment sparen we hiermee niet zoveel tijd uit, maar ook hier moet je je voorstellen dat je met nog langere namen of extra niveaus in je namespace zit. En geloof me als ik zeg dat de namen lang kunnen worden als je meerdere niveaus gebruikt.
Samenvatting
Namespaces geven je de mogelijkheid om je types te groeperen in een "benoemde groep", dit laat je toe om je code beter te structureren alsook om meerdere klassen te hebben met dezelfde naam (zolang deze in aparte namespaces zitten).