TOC
Classes:

Namespaces

In one of the first articles, we briefly discussed namespaces. You probably recognize the keyword, because it's found in most files containing C# code, usually almost in the top. A namespace is essentially a way to group a set of types, e.g. classes, in a named space of its own. When Visual Studio generates a new project for you, it also generates a default namespace in which it places your first file (at least this is true for the Console App project type). It could look like this:

using System;  

namespace MyProject  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
                // More code below this....

In this case, the namespace "MyProject" is now a part of the application and when using its classes outside of it, you will have to prefix the class name with the namespace name. You see the exact same thing when you want to use something burried deep down in the .NET framework, like this:

System.IO.File.ReadAllText("test.txt");

In this case, we use the ReadAllText() method found on the File class which exists in the System.IO namespace. Of course, it would be tedious to write such a long name each time you wanted to use a class from a namespace, so C# allows you to "import" an entire namespace into the scope of your file with a using statement. Again, you might already know them, because you can usually find them at the top of your C# files. For the example above, if we would need the File class more than once, it would make sense to import the System.IO namespace with a using statement like this:

using System;
using System.IO;
// More using statements here...

Why do you need namespaces?

If you have just started programming, you might wonder what we need namespaces for. Why not just put all your classes in the same namespaces so that they are always accessible? You have a valid point, but only if your project is very small. As soon as you start adding more and more classes, it makes very good sense to separate them into namespaces. It simply makes it easier for you to find your code, especially if you places your files in corresponding folders - in fact, if you add a folder to your project and then add a class to it, Visual Studio will automatically put it in a corresponding namespace. So, if you create a folder in MyProject called MyFolder, classes added to this folder will, by default, be placed in a namespace called MyProject.MyFolder.

A great example of why namespaces are needed is the .NET framework itself. Just think if ALL the classes in the framework were just floating around in a global namespace - it would be a mess! Instead, they have organized them nicely, with System as the root namespace for most classes and then sub-namespaces like System.IO for input/output stuff, System.Net for network related stuff and System.Net.Mail for mail-related stuff.

Name Conflicts with Namespaces

As mentioned, namespaces are also there to encapsulate your types (usually classes), so that they can exist within their own domain. This also means that you are free to create classes with the same name as the ones found elsewhere in your project or even in the .NET framework. For instance, you might decide that you need a File class of your own. As we saw in the previous examples, such a class already exists in the System.IO namespace, but you are free to create one in your own namespace, like this:

using System;  

namespace MyProject.IO  
{  
    class File  
    {  
        public static void HelloWorld()  
        {  
            Console.WriteLine("Hello, world!");  
        }  
    }  
}

Now when you want to use it in your project, e.g. in your Program.cs Main method (if you're working on a Console App, like I am), you can either write the full name:

MyProject.IO.File.HelloWorld();

But you can also import the namespace, like you can with any other namespace (built-in or user-defined), thanks to the using statement. Here's a more complete example:

using System;
using MyProject.IO;

namespace MyProject
{
    class Program
    {
        static void Main(string[] args)
        {
            File.HelloWorld();
        }
    }
}

So far, so good! However, what if you also want to use the File class from the System.IO namespace? Well, this is where the trouble starts, because if you import that namespace as well, with a using statement, the compiler no longer knows which File class you're referring to - our own or the one from the System.IO namespace. This can be solved by only importing one of the namespaces (ideally the one from which you use the most types) and then fully qualifying the name of the other one, like in this example:

using System;
using System.IO;

namespace MyProject
{
    class Program
    {
        static void Main(string[] args)
        {
            MyProject.IO.File.HelloWorld();
        }
    }
}

But it's a bit cumbersome to type each time, especially if your class is even deeper nested in namespaces, e.g. MyProject.FileStuff.IO.File. Fortunately, C# has a solution for that.

Using Alias Directive

To shorten the name of the namespace a lot, you can import the namespace under a different name, with a Using Alias Directive. Notice how I do just that in the next example:

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();
        }
    }
}

The magic happens in the third line, where I pull in the MyProject.IO namespace and give it a shorter name (MyIO), which can then be used when we want to access types from it. At this point, we're not saving a lot of keystrokes, but again you should imagine even longer names and levels of namespaces, and believe me, they can get quite long and nested.

Summary

Namespaces gives you the opportunity to encapsulate your types into "named spaces", which allows you to get a better structure in your code, as well as have multiple classes with the same name, as long as they exist in separate namespaces.

This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!