Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Tip
New to developing software? Start with the Get started tutorials first. They introduce namespaces and using directives as you write your first programs.
Experienced in another language? Namespaces in C# work similarly to packages in Java or modules in Python. Skim ahead to the syntax you need.
Namespace declarations and using directives are related language features. A namespace declaration puts your types into an organized structure. A namespace groups related types together and prevents naming collisions. A using directive lets your program consume those types by their simple names. You don't have to spell out the full namespace path at every use.
You've already used namespaces in every C# program you've written. Every .NET type belongs to a namespace, and every using directive at the top of a file references one. For example, Console and Math belong to the System namespace, so their fully qualified names are System.Console and System.Math. Collection types like List<T> and Dictionary<TKey, TValue> belong to System.Collections.Generic. A single using directive for any of these namespaces lets you refer to all its types by their simple names. You write List<T> instead of System.Collections.Generic.List<T> everywhere you use it.
This article provides more background on how namespaces and using directives work, and shows examples of patterns you've already encountered in .NET libraries.
A namespace contains types. Every .NET type belongs to a namespace. For example, consider System.Threading.Tasks.Task: the type Task belongs to the System.Threading.Tasks namespace.
It's good practice to group related or similar types in the same namespace, and that's what .NET does with the types it provides. The System.Collections.Generic namespace contains collection-related types and the System.IO namespace contains types related reading and writing files, directories, and data. The System namespace contains fundamental types like Math, DateTime, and Console.
The following example shows how namespaces work together with using directives in a typical C# file:
using System.Globalization;
namespace MyApp.Services;
class Greeter
{
public string Greet(string name)
{
var culture = CultureInfo.CurrentCulture;
return $"Hello, {name}! Culture: {culture.Name}";
}
}
In the preceding sample, the using directive means you can use the System.Globalization.CultureInfo by the name CultureInfo without specifying the full name of System.Globalization.CultureInfo. The namespace directive declares that the Greeter class is part of the MyApp.Services namespace. Its fully qualified name is MyApp.Services.Greeter.
Namespace declarations
A namespace declaration assigns your types to a named group. Every type you write should belong to a namespace. The namespace name typically mirrors the folder structure of your project. For example, types in a Services/Payments folder often belong to the MyApp.Services.Payments namespace.
Namespaces use the . operator to express hierarchy, such as System.Collections.Generic. Namespace names must be valid C# identifier names.
File-scoped namespaces
Use the file-scoped syntax when all types in a file belong to the same namespace. Add a semicolon after the namespace declaration, and it applies to the entire file. You don't need extra braces or indentation:
namespace MyApp.Models;
class Customer
{
public required string Name { get; init; }
public string? Email { get; init; }
public override string ToString() => $"{Name} ({Email ?? "no email"})";
}
File-scoped namespaces reduce nesting and make files easier to read. You can only have one file-scoped namespace declaration per file.
Tip
Use file-scoped namespaces in new code. Most .NET templates and code analyzers recommend this style.
Block-scoped namespaces
Use block-scoped syntax when you need to declare more than one namespace in the same file. This style adds an extra level of indentation.
Important
It's considered bad-practice to declare more than one namespace in the same file. The more common scenario is to use file-scoped namespaces.
The following snippet is an example of a block-scoped namespace:
namespace MyApp.Models
{
class Product
{
public required string Name { get; init; }
public decimal Price { get; init; }
public override string ToString() => $"{Name}: {Price:C}";
}
}
Using directives
Without a using directive, you must refer to every type by its fully qualified name, the complete namespace path plus the type name:
static void ShowFullyQualified()
{
// Without a using directive, use the fully qualified name:
System.Console.WriteLine("Hello from fully qualified name!");
}
A using directive at the top of a file imports a namespace so you can use its types by their simple names:
static void ShowShortName()
{
// With 'using System;' (or implicit usings enabled), use the short name:
Console.WriteLine("Hello from short name!");
}
For more information, see the using directive.
Global using directives
If you write the same using directives in every file, global using directives let you declare them once for your entire project. Place them in any file. Many teams create a dedicated GlobalUsings.cs file:
global using System.Text;
global using System.Text.Json;
After declaring a global using, every file in the project can refer to types from that namespace by using simple names without an additional using directive.
Implicit usings
The .NET SDK automatically generates global using directives for the most common namespaces based on your project type. Enable implicit usings by setting <ImplicitUsings>enable</ImplicitUsings> in your project file. For example, a console app project automatically imports System, System.Collections.Generic, System.IO, System.Linq, System.Threading, and System.Threading.Tasks. The current SDK enables ImplicitUsings when you create a new project by using dotnet new.
For more information, see Implicit using directives.
Static using directives
A static using directive imports the static members of a type so you can call them without the type name prefix:
using static System.Math;
namespace MyApp.Utilities;
class CircleCalculator
{
public static double CalculateArea(double radius) => PI * Pow(radius, 2);
public static double CalculateCircumference(double radius) => 2 * PI * radius;
}
Static usings work well for utility classes like Math and Console that you call frequently.
Type and namespace aliases
A using alias creates a shorthand name for a type or namespace. Aliases are useful for long generic types, resolving naming conflicts, and improving readability:
using CustomerList = System.Collections.Generic.List<MyApp.Models.Customer>;
namespace MyApp.Services;
class CustomerService
{
public CustomerList GetTopCustomers()
{
CustomerList customers = [new() { Name = "Alice" }, new() { Name = "Bob" }];
return customers;
}
}
Starting with C# 12, you can alias any type, including tuples and pointer types:
using Point = (double X, double Y);
namespace MyApp.Geometry;
class Shape
{
public static double Distance(Point a, Point b)
{
var dx = a.X - b.X;
var dy = a.Y - b.Y;
return Math.Sqrt(dx * dx + dy * dy);
}
}
For more advanced scenarios where two assemblies define the same fully qualified type name, use extern alias to disambiguate between them.