File-Scoped Namespaces in C#



A file-scoped namespace in C# is a way to declare a namespace that applies to the entire file. It is written in a single line followed by a semicolon ; without using curly braces {}. This feature was introduced in C# 10.

Namespaces are used to group related classes, interfaces, and other types under a single name to avoid naming conflicts. A naming conflict happens when different parts of a project use the same name, which can confuse the compiler.

Earlier, we used block-scoped namespaces where everything was wrapped inside curly braces {} but this added unnecessary indentation, especially when the file contained only one or two classes.

File-Scoped Namespaces

A file-scoped namespace is a namespace declaration that applies to the entire file without using braces {}. We write the namespace name followed by a semicolon (;) and every type such as a class, record, or interface in that file automatically belongs to that namespace

Syntax for File-Scoped Namespace

Following is the syntax for declaring a file-scoped namespace.

namespace NamespaceName;

Here, NamespaceName represents the name of the namespace we are defining.

Example

In this example, the Logger class belongs to the TutorialsPoint.Services namespace. There are no curly braces which makes the code cleaner and easier to read.

namespace TutorialsPoint.Services;

public class Logger {
   public void Log(string message){
      Console.WriteLine(message);
   }
}

Rules for File-Scoped Namespaces

File-scoped namespaces follow a few simple rules −

  • Always end the namespace declaration with a semicolon (;).
  • Only one file-scoped namespace is allowed per file.
  • All types written after the declaration automatically belong to that namespace.
  • We can include any type like class, struct, enum, interface, or record.

Example

In this example, we define the User class, the Product class, and the Status enum. We can see that all these types belong to the same Project.Models namespace without using any braces.

namespace Project.Models;

public class User {
   public string Name { get; set; } = "";
}

public class Product {
   public string Title { get; set; } = "";
}

public enum Status{
   Active,
   Inactive
}

Traditional Block-Scoped Namespaces

Before file-scoped namespaces were introduced, we used the block-scoped style where the namespace and its contents were wrapped inside curly braces({}). This structure adds extra indentation as projects grow, which makes the code look less clean.

Example

Here's an example of how we define a namespace using curly braces in the traditional block-scoped way.

namespace Tutorialspoint.Services {
   public class Logger {
      public void Log(string message) {
         Console.WriteLine(message);
      }
   }
}

Access Modifiers

Access modifiers control the visibility of classes and members in our code. File-scoped namespaces do not change how they work. We can use public, internal, and private the same way as before.

Example

Here's an example of how the Database class is defined as internal, and the Repository class is defined as public.

namespace Project.Data;

internal class Database { }

public class Repository { }

Using File-Scoped Namespaces with Global Usings

File-scoped namespaces work perfectly with global using directives. This means we don't have to repeat the same using statements in multiple files and using them together keeps our project structure cleaner and easier to manage.

Example

Here's an example where we combine both file-scoped namespace syntax and global using directive. We define System globally, so we don't need to import System again in each file.

global using System;

namespace Project.Logging;

public class Logger {
   public void Log(string message){
      Console.WriteLine(message);
   }
}

Difference Between Block-Scoped and File-Scoped Namespaces

Following table shows the key differences between block-scoped and file-scoped namespaces −

Feature Block-Scoped Namespace File-Scoped Namespace
Syntax Uses { } braces Ends with ;
Indentation Adds extra indentation Cleaner, no extra indentation
Readability Slightly nested Simple and easy to read
C# Version Before C# 10 C# 10 and later

Conclusion

In this chapter, we learned how file-scoped namespaces in C# 10 make our code simpler and cleaner by applying a namespace to the entire file with just a single line ending in a semicolon. Instead of wrapping everything inside curly braces, we can now write our classes, interfaces, and other types directly at the top level.

Advertisements