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.
The Sample Project
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:
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!
Happy Coding!