DEV Community

mohamed Tayel
mohamed Tayel

Posted on

Mastering C# Fundamentals: Namespaces Grouping Your Own Classes and Types

Meta Description:
Explore the importance of namespaces in C# programming and learn how to group classes and types effectively. This article covers the basics of creating custom namespaces, the difference between traditional and file-scoped namespaces, and practical assignments of varying complexity to reinforce your understanding. Gain insights into organizing your code to avoid naming collisions and improve maintainability.

In this article, we will explore namespaces from a fresh perspective, focusing on how to effectively group our own classes and types within them. As we learned in the previous module, the .NET Base Class Library (BCL) organizes its types to prevent naming collisions using namespaces. This organization resembles a folder structure, but it's essential to understand that it is a virtual organization—no physical folders are required. This analogy helps us grasp how namespaces function, allowing multiple classes to have the same name as long as they reside in different namespaces.

The Importance of Namespaces

Namespaces are crucial in C# programming because they allow us to create multiple classes with the same name without conflicts. Without namespaces, every class must have a unique name throughout the application. By using namespaces, we only need to ensure uniqueness within the same namespace. This practice is common in .NET and should be adopted by all C# developers to maintain organized code.

Creating Custom Namespaces

Creating a namespace is simple; it’s essentially a string that groups related classes or types. Once a class is defined within a namespace, it gains a fully qualified name, which includes both the namespace and the class name. To utilize a class from a namespace, we add a using statement at the top of our code file.

Here’s a basic example of how to create and use a custom namespace:

namespace MyApp.HR
{
    public class Employee
    {
        public string Name { get; set; }
        public int EmployeeId { get; set; }
    }
}
Enter fullscreen mode Exit fullscreen mode

In the example above, we created a namespace called MyApp.HR and included the Employee class within it. To access this class in another file, we simply add the following line at the top:

using MyApp.HR;
Enter fullscreen mode Exit fullscreen mode

Traditional vs. File-Scoped Namespaces

In C# 10, a new syntax called file-scoped namespaces was introduced. Traditionally, namespaces are defined with curly braces, encompassing all code within them:

namespace MyApp.HR
{
    public class Employee
    {
        // Class implementation
    }
}
Enter fullscreen mode Exit fullscreen mode

With file-scoped namespaces, we can simplify this structure, allowing for a cleaner appearance:

namespace MyApp.HR;

public class Employee
{
    // Class implementation
}
Enter fullscreen mode Exit fullscreen mode

Both methods achieve the same goal, and the choice between them depends on personal preference.

Assignment Levels

Let’s put this knowledge into practice with a series of assignments of varying complexity.

Easy Level: Creating a Namespace and Grouping Classes

For the easy assignment, create an application with a few classes organized into different namespaces.

  1. Create a project in Visual Studio named MyApp.
  2. Add a namespace called MyApp.HR and create two classes: Employee and Department.
  3. Add another namespace called MyApp.Sales and create a class called Customer.

Here's the structure:

namespace MyApp.HR
{
    public class Employee
    {
        public string Name { get; set; }
        public int Id { get; set; }
    }

    public class Department
    {
        public string DepartmentName { get; set; }
    }
}

namespace MyApp.Sales
{
    public class Customer
    {
        public string CustomerName { get; set; }
    }
}
Enter fullscreen mode Exit fullscreen mode

Now, create a new file called Program.cs and use these classes by adding the appropriate using statements:

using MyApp.HR;
using MyApp.Sales;

namespace MyApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Employee employee = new Employee { Name = "John Doe", Id = 123 };
            Department department = new Department { DepartmentName = "HR" };
            Customer customer = new Customer { CustomerName = "Jane Smith" };

            Console.WriteLine($"Employee: {employee.Name}, Department: {department.DepartmentName}, Customer: {customer.CustomerName}");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Medium Level: Organizing Classes in Subfolders and Using File-Scoped Namespaces

For the medium-level assignment, we will add structure by organizing classes into subfolders and using file-scoped namespaces.

  1. In Visual Studio, create subfolders named HR and Sales.
  2. Move the Employee and Department classes into the HR folder, and the Customer class into the Sales folder.
  3. Update the classes to use file-scoped namespaces.

Here’s how the classes would look:

// In HR/Employee.cs
namespace MyApp.HR;

public class Employee
{
    public string Name { get; set; }
    public int Id { get; set; }
}

// In HR/Department.cs
namespace MyApp.HR;

public class Department
{
    public string DepartmentName { get; set; }
}

// In Sales/Customer.cs
namespace MyApp.Sales;

public class Customer
{
    public string CustomerName { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Now, update Program.cs to utilize these classes:

using MyApp.HR;
using MyApp.Sales;

namespace MyApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Employee employee = new Employee { Name = "Alice", Id = 456 };
            Department department = new Department { DepartmentName = "Sales" };
            Customer customer = new Customer { CustomerName = "Bob Brown" };

            Console.WriteLine($"Employee: {employee.Name}, Department: {department.DepartmentName}, Customer: {customer.CustomerName}");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Difficult Level: Creating Multiple Namespaces and Using Fully Qualified Names

For the difficult-level assignment, we will create a more complex structure involving multiple namespaces and demonstrate how to use fully qualified names.

  1. Create new classes under different folders and namespaces:
    • Finance namespace containing Account and Transaction classes.
    • Operations namespace containing Order and Shipment classes.

Here’s the complete structure:

// In Finance/Account.cs
namespace MyApp.Finance;

public class Account
{
    public string AccountNumber { get; set; }
    public decimal Balance { get; set; }
}

// In Finance/Transaction.cs
namespace MyApp.Finance;

public class Transaction
{
    public decimal Amount { get; set; }
    public DateTime Date { get; set; }
}

// In Operations/Order.cs
namespace MyApp.Operations;

public class Order
{
    public string OrderNumber { get; set; }
    public decimal TotalAmount { get; set; }
}

// In Operations/Shipment.cs
namespace MyApp.Operations;

public class Shipment
{
    public string ShipmentTrackingNumber { get; set; }
    public DateTime ShipmentDate { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Updating the Program.cs File

Now, we’ll utilize these new classes in the Program.cs file, demonstrating how to use fully qualified names to access classes from different namespaces without using statements.

using MyApp.HR;
using MyApp.Sales;

namespace MyApp
{
    class Program
    {
        static void Main(string[] args)
        {
            // Using classes from the HR namespace
            Employee employee = new Employee { Name = "Alice", Id = 456 };
            Department department = new Department { DepartmentName = "Sales" };
            Customer customer = new Customer { CustomerName = "Bob Brown" };

            Console.WriteLine($"Employee: {employee.Name}, Department: {department.DepartmentName}, Customer: {customer.CustomerName}");

            // Using classes from the Finance namespace
            Finance.Account account = new Finance.Account { AccountNumber = "A123", Balance = 1000.50m };
            Finance.Transaction transaction = new Finance.Transaction { Amount = 250.00m, Date = DateTime.Now };

            Console.WriteLine($"Account Number: {account.AccountNumber}, Balance: {account.Balance}");
            Console.WriteLine($"Transaction Amount: {transaction.Amount}, Date: {transaction.Date}");

            // Using classes from the Operations namespace
            Operations.Order order = new Operations.Order { OrderNumber = "ORD001", TotalAmount = 150.75m };
            Operations.Shipment shipment = new Operations.Shipment { ShipmentTrackingNumber = "TRACK123", ShipmentDate = DateTime.Now };

            Console.WriteLine($"Order Number: {order.OrderNumber}, Total Amount: {order.TotalAmount}");
            Console.WriteLine($"Shipment Tracking Number: {shipment.ShipmentTrackingNumber}, Shipment Date: {shipment.ShipmentDate}");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

In this article, we delved into the concept of namespaces in C#, highlighting their importance in organizing code effectively. We covered:

  • The necessity of namespaces for avoiding naming collisions.
  • How to create custom namespaces and utilize using statements.
  • Differences between traditional and file-scoped namespaces.
  • Structuring code through multiple assignments of varying complexity.

Assignments Recap

  1. Easy Level: Create a simple project with basic namespaces and classes.
  2. Medium Level: Organize classes into subfolders and use file-scoped namespaces.
  3. Difficult Level: Create multiple namespaces, demonstrate class usage, and apply fully qualified names.

By completing these assignments, you'll enhance your understanding of namespaces and improve your ability to organize your C# code. Happy coding!

Top comments (0)