All code needs some kind of organization, and the most basic way to provide that organization in C# programs is through the use of namespaces.

A shooting star streaks through the purple twilight sky, with mountains visible in the foreground.
Make a wish! Photo by Vincentiu Solomon / Unsplash

The Sample Project

exceptionnotfound/CSharpInSimpleTerms
Contribute to exceptionnotfound/CSharpInSimpleTerms development by creating an account on GitHub.
Project for this post: 11Namespaces

Basic Namespaces

Namespaces in C# are used to organize code. Think of them as containers for related classes, methods, and objects.

System.Console.WriteLine("System is a namespace");

In the above line, System is a namespace and Console is a class in that namespace.

We include specific namespaces in a given .cs file with the using keyword. A very basic but complete .cs file will have a set of using statements, the namespace for the file, a class or other object, and any members of that object.

using System;

namespace ProgramName //Namespace
{
    class Program //Class
    {
        public static void Main() //Class member
        {
            Console.WriteLine("Starting application...");
        }
    }
}

Visual Studio and other Integrated Development Environment (IDE) programs will create a default namespace for any new projects; this is generally the same as the project name.

Namespaces and Organization

The primary reason we use non-default namespaces (e.g. ones we create ourselves) is for better code organization. For example, in a large project, we might want to separate our models from our data access layer, e.g. whatever classes need to access a database or other data store.

In such a project, we might have the following namespaces:

using MyProject.Models.Users;
using MyProject.Models.Vehicles;
using MyProject.DataAccess.Repositories.Users;
using MyProject.DataAccess.Repositories.Vehicles;

Truth is, there's no hard rules about when to create custom namespaces and when not to. It depends on each project, and the preferences of the developers involved. I would recommend though that it's better to have too many namespaces rather than too few.

Namespace Aliases

It may happen that two different classes have the same name but are in distinct namespaces. This happens more often in larger projects.

Let's imagine that we have two User classes in different namespaces:

namespace OtherAPI.Models
{
    public class User { /*...*/ }
}

namespace MyProject.DTOs
{
    public class User { /*...*/ }
}

Let's also say that we need to use both of these classes in a third class in yet another namespace. A naive solution would be to use the using keyword to include those namespaces, but this will fail with a compilation error:

using OtherAPI.Models;
using MyProject.DTOs;

namespace MyProject
{
    public class OtherClass
    {
        public User User1 { get; set; }

        public User User2 { get; set; }
    }
}
Error: 'User' is an ambiguous reference between 'MyProject.DTOs.User' and 'OtherAPI.Models.User'.

Instead, we could solve this problem using namespace aliases:

using models = OtherAPI.Models; //Namespace alias
using MyProject.DTOs;

namespace MyProject
{
    public class OtherClass
    {
        public models::User User1 { get; set; } //Use of the alias

        public User User2 { get; set; } //MyProject.DTOs.User
    }
}

Please note, we don't need to have the situation described above to use namespace aliases. They can be used at any time.

Namespace Nesting

It is possible to create nested namespaces:

namespace N1
{
    class C1 { /*...*/ }
    
    namespace N2
    {
        class C2 { /*...*/ }
    }
}

If we want to use the class C2 we can call it using the fully-qualified namespace or using keyword.

var myVar = new N1.N2.C2();

//OR

using N1.N2;
var myVar = new C2();

We can also add other classes to the nested namespace N2 by qualifying the namespace:

namespace N1.N2
{
    class C3 { /*...*/ }
}

Glossary

  • Namespace - an identifier for a group of C# classes, methods, objects, etc.
  • Fully-qualified - when we use the entire name of a namespace, we say that is the fully-qualified namespace.

New Keywords

  • namespace - Creates a namespace with the given identifier.
  • using - Specifies a namespace to include in a C# .cs file. Objects in that namespace can then be referenced directly in said file.

Summary

Namespaces are a way to group related C# objects together by giving them a common identifier. Namespaces can be nested, and can be referenced using either the fully-qualified namespace or the using keyword. We can also alias namespaces to make our code more readable when dealing with classes with the same name.

Namespaces are pretty straightforward, but if you have questions about them, please ask. The comments below are open.

In the next post in this series, we use our class knowledge to see how to handle unexpected errors (called exceptions) encountered while our C# programs are running. You'll want to catch this one!

C# in Simple Terms - Exceptions and Exception Handling
Let’s learn how to create, throw, catch, re-throw, and handle exceptions in C#!

Happy Coding!