Namespaces #
Namespaces work on the same principle as in C++. The difference is the way elements are extracted from a namespace; in C#, this is done using the .
operator. Additionally, there are several ways to define namespaces.
The exception is the global namespace, from which elements are extracted using the
global::
operator. In practice, however, this is rarely useful (if at all).
Outer.Middle.Inner.ClassA a;
namespace Outer
{
namespace Middle
{
namespace Inner
{
class ClassA {}
}
}
}
namespace Outer.Middle.Inner
{
class ClassB {}
}
namespace Outer.Middle.Inner; // Applies to the end of the file
class classC {}
The using
directive
#
The using
directive allows you to import namespaces into the current file, so you don’t have to use fully qualified names for the types they contain.
using Outer.Middle.Inner;
Outer.Middle.Inner.ClassB b1;
ClassB b2; // This is also possible
namespace Outer.Middle.Inner
{
class ClassB {}
}
Static using
#
Static using
imports types, not namespaces. The effect is that you can use all static members of classes, and in the case of enums, their elements, without providing the full qualifier.
using static System.Console; // class
using static System.DayOfWeek; // enum
WriteLine("Hello, world!");
WriteLine(Monday); // without using, it would be `DayOfWeek.Monday`
Global using
#
Global using
propagates to all files in the project. It must be placed before other using
directives.
global using System;
global using System.IO;
Implicit global using
#
Since .NET 6.0, SDK-style projects have an option that adds a file with global using
directives to your program when it is built.
These directives depend on the selected SDK; for “Microsoft.NET.Sdk” they are:
- System
- System.Collections.Generic
- System.IO
- System.Linq
- System.Net.Http
- System.Threading
- System.Threading.Tasks
You can disable this option by setting the ImplicitUsings
property to false
in the project file.
Type aliases #
The using
directive can also be used to introduce an alias for a single type or namespace, instead of importing everything from a namespace. This is useful when two types with the same name from different namespaces conflict, and you want to use both, e.g., Vector3
from System.Numerics
and Vector3
from an external library. Since C# 12, we can alias almost any type, including arrays and tuples.
using Vec3 = System.Numerics.Vector3;
using Refl = System.Reflection;
using NumberList = double[];
using PersonInfo = (string Name, int Age);
Vec3 vector;
Refl.PropertyInfo propInfo;
NumberList numbers = { -0.5, 0.5 };
PersonInfo person = ("Alice", 42);