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