Exploring C# 10: Global Using Declarations
Tags: csharp, dotnet
Published: 2021-10-24 16:37:12

---
title: Exploring C# 10: Global Using Declarations
published: true
date: 2021-10-21 03:18:57 UTC
tags: csharp, dotnet
canonical_url: https://www.daveabrock.com/2021/10/21/csharp-10-global-usings/
---

Welcome back to my series on new C# 10 features. I kicked off this series by writing about [file-scoped namespaces](https://www.daveabrock.com/2021/10/05/csharp-10-file-scoped-namespaces/), a simple but powerful way to remove unnecessary verbosity from your C# code. This time, we're talking about a new feature that achieves similar goals: global using declarations.

To see how this works, let's revisit my model from the last post, a `Superhero`:

```csharp
namespace SuperheroApp.Models;

public class Superhero
{
   public string? FirstName { get; set; }
   public string? LastName { get; set; }
   public string? StreetAddress { get; set; }
   public string? City { get; set; }
   public int? MaxSpeed { get; set; }
}
```

Let's say I wanted to do some basic work with this model in a standard C# 10 console application. It would look something like this.

```csharp
using SuperheroApp.Models;

var heroList = new List<Superhero>()
{
    new Superhero
    {
        FirstName = "Tony",
        LastName = "Stark",
        StreetAddress = "10880 Malibu Point",
        City = "Malibu",
        MaxSpeed = 500
    },
    new Superhero
    {
        FirstName = "Natasha",
        LastName = "Romanova",
        MaxSpeed = 200
     }
};

foreach (var hero in heroList)
    Console.WriteLine($"Look, it's {hero.FirstName} {hero.LastName}!");

Console.WriteLine($"The first superhero in the list is {heroList.First().FirstName}.");
```

You'll notice that [thanks to top-level statements](https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/program-structure/top-level-statements), the file is already looking pretty slim. If I create a new file, like `GlobalUsings.cs`, I could store any usings that I want to be shared across my project's C# files. While you can declare global usings anywhere, it's probably a good idea to isolate it somewhere. (This is scoped for the project and not the solution, so if you want this across multiple files you'd want to specify global usings in every project.)

```csharp
global using ConsoleApp6.Models;
```

When I go back to my `Program.cs` file, Visual Studio reminds me that `Superhero.Models` is referenced elsewhere (in my `GlobalUsings.cs`), so it can be safely removed.

![](https://www.daveabrock.com/content/images/2021/10/image-1.png)

I can also use the `global static` keyword when I use common static methods, like the `Math` class or writing to `Console`.  While static usings aren't new—they've been around since C# 6—I can use it freely with global usings. Let's update my `GlobalUsings.cs` file to the following:

```csharp
global using SuperheroApp.Models;
global using static System.Console;
```

Back in my `Program.cs`, Visual Studio tells me I don't need to use `Console`.

![](https://www.daveabrock.com/content/images/2021/10/image-2.png)

Aside from supporting standard namespaces (and system ones) and static namespaces, you can also use aliases. Let's say I wanted to globally use `System.DateTime` and alias it as `DT`. Here's how my `GlobalUsings.cs` file looks now:

```csharp
global using SuperheroApp.Models;
global using static System.Console;
global using DT = System.DateTime;
```

Going back to my main `Program.cs`, here's how everything looks now:

```csharp
var heroList = new List<Superhero>()
{
    new Superhero
    {
        FirstName = "Tony",
        LastName = "Stark",
        StreetAddress = "10880 Malibu Point",
        City = "Malibu",
        MaxSpeed = 500
    },
    new Superhero
    {
        FirstName = "Natasha",
        LastName = "Romanova",
        MaxSpeed = 200
     }
};

foreach (var hero in heroList)
    WriteLine($"Look, it's {hero.FirstName} {hero.LastName}!");

WriteLine($"The first superhero in the list is {heroList.First().FirstName}.");
WriteLine($"Last ran on {DT.Now}");

```

## Are some common namespaces globally available by default?

When I created a collection and read from it, I'm using calls from a few standard Microsoft namespaces: `System.Collections.Generic` and `System.Linq`. You may have noticed something: why didn't I need to explicitly include these namespaces in a global usings file? The answer lies in the `obj/Debug/net6.0` folder. After you build your project, you'll notice a `GlobalUsings.g.cs` file, which contains _implicit usings_. Enabled by default in .NET 6, you don't need to explicitly include them.

```csharp
// <auto-generated/>
global using global::System;
global using global::System.Collections.Generic;
global using global::System.IO;
global using global::System.Linq;
global using global::System.Net.Http;
global using global::System.Threading;
global using global::System.Threading.Tasks;
```

The funky `global::` syntax ensures that you don't see collisions if you have your own namespaces. For example, if I had a few drinks one night and decided to write my own (very buggy) I/O library and call it `DaveIsCool.System.IO`, this ensures I'm using the Microsoft namespace.

These usings are driven by an `<ImplicitUsings>` flag in my project file.

```xml
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
</Project>
```

If you remove the `<ImplicitUsings>` line, for example, you would see build errors:

![](https://www.daveabrock.com/content/images/2021/10/image-3.png)

A word of caution: in .NET 6 implicit usings are enabled by default, so if implicit usings aren't for you, this is where you would disable it. For details, take a look at [the following document](https://docs.microsoft.com/en-us/dotnet/core/compatibility/sdk/6.0/implicit-namespaces) from the .NET team.

## Can I incorporate global usings with project configuration?

To me, it does seem a little strange to be using C# source files to configure project details. If you don't want to use a C# file to specify your global using declarations, you can delete your file and [use MSBuild syntax instead](https://devblogs.microsoft.com/dotnet/announcing-net-6-release-candidate-2/#global-usings).

Once you open your project file, you can encapsulate your global usings in an `<ItemGroup>`, like so:

```xml
<ItemGroup>
    <Using Include="SuperheroApp.Models"/>
    <Using Include="System.Console" Static="True" />
    <Using Include="System.DateTime" Alias="DT" />
</ItemGroup>
```

## Do I have to use these?

Much like other .NET 6 improvements, you can use it as much or as little as you want. You can use nothing but global and implicit `using` statements, mix them with regular namespace declarations, or do things as we've always done before. It's all up to you.

Between C# 9 top-level statements, implicit and global usings, and file-scoped namespaces, the C# team is removing a lot of clutter from your C# files. For example, here's how our `Program.cs` file would look in C# 8 or older.

```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using SuperheroApp.Models;

namespace SuperheroApp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var heroList = new List<Superhero>()
            {
                new Superhero
                {
                    FirstName = "Tony",
                    LastName = "Stark",
                    StreetAddress = "10880 Malibu Point",
                    City = "Malibu",
                    MaxSpeed = 500
                },
                new Superhero
                {
                    FirstName = "Natasha",
                    LastName = "Romanova",
                    MaxSpeed = 200
                 }
            };

            foreach (var hero in heroList)
                Console.WriteLine($"Look, it's {hero.FirstName} {hero.LastName}!");

            Console.WriteLine($"The first superhero in the list is {heroList.First().FirstName}.");
            Console.WriteLine($"Last ran on {DT.Now}");
        }
    }
}

```

With top-level statements and global and implicit usings, we now have this.

```csharp
var heroList = new List<Superhero>()
{
    new Superhero
    {
        FirstName = "Tony",
        LastName = "Stark",
        StreetAddress = "10880 Malibu Point",
        City = "Malibu",
        MaxSpeed = 500
    },
    new Superhero
    {
        FirstName = "Natasha",
        LastName = "Romanova",
        MaxSpeed = 200
     }
};

foreach (var hero in heroList)
    WriteLine($"Look, it's {hero.FirstName} {hero.LastName}!");

WriteLine($"The first superhero in the list is {heroList.First().FirstName}.");
WriteLine($"Last ran on {DT.Now}");
```

What do you think? Let me know in the comments. Stay tuned for my next topic on CRUD endpoints with the new .NET 6 Minimal APIs.