C# Namespaces

Organizing code with namespaces

📦 What are Namespaces?

Namespaces organize code into logical groups, preventing naming conflicts and improving code structure. They act like folders for your classes, providing a hierarchical organization system that makes large codebases manageable and maintainable.


// Defining a namespace
namespace MyApplication
{
    class Program
    {
        // Your code here
    }
}
                                    

Note:

Namespaces organize and group related classes

Key Namespace Concepts

📁

Organization

Group related classes together

namespace MyApp.Models
🔗

Using Directive

Import namespaces into your code

using System;
🌳

Nested Namespaces

Create hierarchical structure

namespace App.Data.Models
🛡️

Avoid Conflicts

Prevent naming collisions

MyApp.User vs System.User

🔹 Creating a Basic Namespace

Namespaces organize code into logical groups, preventing naming conflicts and improving project structure. Defined with the namespace keyword, they act as containers for classes, interfaces, and other types. For example, namespace MyApplication { class Program { } } encapsulates program logic. This modularity aids in large-scale development, enabling better code management, reuse, and clarity by separating concerns into distinct, scoped units.

using System;

namespace MyApplication
{
    class Program
    {
        static void Main()
        {
            Console.WriteLine("Hello from MyApplication namespace!");
        }
    }

    class Helper
    {
        public static void PrintMessage()
        {
            Console.WriteLine("Helper class in MyApplication");
        }
    }
}

Output:

Hello from MyApplication namespace!

🔹 Using Directive

The using directive imports namespaces, allowing unqualified type references and reducing code verbosity. Placed at the file's top, it eliminates the need for fully qualified names like System.Console.WriteLine. This simplifies code maintenance and enhances readability. Additionally, static using directives (e.g., using static System.Math) import static members, further streamlining mathematical or utility operations in your C# applications.

// Without using directive
System.Console.WriteLine("Hello");
System.Collections.Generic.List<int> numbers = new System.Collections.Generic.List<int>();

// With using directive
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        Console.WriteLine("Hello"); // Much cleaner!
        List<int> numbers = new List<int> { 1, 2, 3 };
        
        foreach (int num in numbers)
        {
            Console.WriteLine(num);
        }
    }
}

Output:

Hello

1

2

3

🔹 Nested Namespaces

Nested namespaces create hierarchical organizations, mirroring folder structures for complex systems. Defined via dot notation (e.g., Company.Product.Module), they provide multiple layers of scope, improving modularity. This is common in enterprise applications to separate features like DataAccess, BusinessLogic, and UI. Such structuring enhances navigability, reduces collisions, and supports scalable architecture by grouping related functionality under parent namespaces.

using System;

namespace Company.Product.Data
{
    class Database
    {
        public static void Connect()
        {
            Console.WriteLine("Connected to database");
        }
    }
}

namespace Company.Product.UI
{
    class Display
    {
        public static void Show()
        {
            Console.WriteLine("Displaying UI");
        }
    }
}

// Using the nested namespaces
using Company.Product.Data;
using Company.Product.UI;

class Program
{
    static void Main()
    {
        Database.Connect();
        Display.Show();
    }
}

Output:

Connected to database

Displaying UI

🔹 Accessing Classes from Different Namespaces

To use classes across namespaces, employ the using directive or fully qualified names. Fully qualified names (e.g., System.Collections.Generic.List<T>) specify the complete path, resolving conflicts. The using directive imports the namespace for concise access. This flexibility ensures clean code while handling naming ambiguities, especially when integrating multiple libraries or modules within large-scale C# projects.

using System;

namespace Geometry
{
    class Circle
    {
        public static void Draw()
        {
            Console.WriteLine("Drawing a circle");
        }
    }
}

namespace Shapes
{
    class Square
    {
        public static void Draw()
        {
            Console.WriteLine("Drawing a square");
        }
    }
}

// Main program
using Geometry;

class Program
{
    static void Main()
    {
        // Using 'using' directive
        Circle.Draw();
        
        // Using fully qualified name
        Shapes.Square.Draw();
    }
}

Output:

Drawing a circle

Drawing a square

🔹 Namespace Aliases

Namespace aliases simplify long or conflicting type names via the using alias directive. For instance, using Geo = MyApp.Geometry; lets you reference Geo.Point instead of the full path. This enhances code clarity and reduces typing, particularly when dealing with external libraries with similar class names. Aliases are invaluable for maintaining readable and conflict-free code in complex, multi-assembly C# solutions.

using System;
using Geo = Company.Application.Geometry;
using Calc = Company.Application.Calculator;

namespace Company.Application.Geometry
{
    class Point
    {
        public static void Display()
        {
            Console.WriteLine("Geometry Point");
        }
    }
}

namespace Company.Application.Calculator
{
    class Point
    {
        public static void Display()
        {
            Console.WriteLine("Calculator Point");
        }
    }
}

class Program
{
    static void Main()
    {
        // Using aliases to avoid confusion
        Geo.Point.Display();
        Calc.Point.Display();
    }
}

Output:

Geometry Point

Calculator Point

🔹 Common Built-in Namespaces

C# provides a rich library of built-in namespaces that organize essential functionalities for .NET development. The System namespace contains fundamental types and base classes. System.Collections.Generic offers type-safe collections like List<T> and Dictionary<TKey, TValue>. For file I/O operations, use System.IO, which includes classes for reading, writing, and managing files and directories. System.Linq introduces powerful query capabilities for collections, enabling efficient data manipulation. Mastering these core namespaces is crucial for writing clean, efficient, and maintainable C# code in any application domain.

using System;                    // Basic types, Console
using System.Collections.Generic; // List, Dictionary
using System.Linq;                // LINQ queries
using System.IO;                  // File operations

class Program
{
    static void Main()
    {
        // System
        Console.WriteLine("Hello World");
        
        // System.Collections.Generic
        List<string> names = new List<string> { "Alice", "Bob", "Charlie" };
        
        // System.Linq
        var filtered = names.Where(n => n.StartsWith("A"));
        Console.WriteLine("Names starting with A: " + string.Join(", ", filtered));
        
        // System.IO
        string path = "example.txt";
        Console.WriteLine($"File exists: {File.Exists(path)}");
    }
}

Output:

Hello World

Names starting with A: Alice

File exists: False

🧠 Test Your Knowledge

Which keyword is used to import a namespace?