Global Usings in C# 10 and .NET 6 In 10 Minutes or Less
Anyone who has scrolled through the top of a C# file knows the ceremony: a column of using statements stacked above every class declaration, repeating themselves from one file to the next. A typical project pulls in the same handful of namespaces over and over, and editing all of them when one needs to change is a chore that pays no actual dividends. C# 10 added the global using directive to remove that repetition project-wide.
In his video "Global Usings in C# 10 and .NET 6 In 10 Minutes or Less," Tim Corey walks through what global usings do, where to put them so the team can find them, and the static variant that lets you drop a class prefix from member calls. He also flags the design pitfall worth keeping in mind: globally importing a namespace exposes the whole project to whatever names live inside it. Anyone who has been copying the same five using lines into every new class will find the cleanup pattern here.
The Repetition Problem
[0:17 - 1:50] Tim starts with a fresh .NET 6 console app and creates a Data folder containing a PersonModel class. Referencing that class from Program.cs requires the expected using GlobalUsings.Data; line at the top of the file. Adding a second class that also needs PersonModel means adding the same using line at the top of that file too. With a half dozen classes, the same import gets written a half dozen times.
This is exactly the situation global using was designed for. Any namespace, type, or static class that the entire project depends on can be declared once and made available to every file without the per-file restatement.
Promoting a Using to Global Scope
[1:50 - 2:24] The syntax is a single keyword in front of the existing directive:
global using GlobalUsings.Data;global using GlobalUsings.Data;That one line, placed in any .cs file in the project, makes GlobalUsings.Data available across every other file in the same project. The other classes that previously needed their own using line for PersonModel no longer require it; the type resolves automatically. The scope stops at the project boundary, so referencing classes from a sibling project still needs the normal project reference plus its own global or per-file using.
What this does not do is hide where types come from. The compiler still resolves PersonModel to its namespace; the namespace is just preimported. Behavior at runtime is identical to writing the same using at the top of every file.
Centralizing Usings in One File
[2:24 - 3:32] Sprinkling global using directives across random files is technically valid but operationally messy. If a new team member sees PersonModel resolve without an obvious import, they have to grep the project to find where it was made global. The evolving convention is to keep all global usings in a single file at the project root, named something predictable like Usings.cs or GlobalUsings.cs:
// Usings.cs at the project root
global using GlobalUsings.Data;
global using System.Text.Json;
global using System.Collections.Concurrent;// Usings.cs at the project root
global using GlobalUsings.Data;
global using System.Text.Json;
global using System.Collections.Concurrent;The file contains nothing else. Anyone joining the project knows exactly one place to look to see what's globally available. This dovetails with file-scoped namespaces and other ceremony-trimming features that have arrived in recent C# releases, all aimed at making project boilerplate easier to read at a glance.
Global Using Static for Method Imports
[3:32 - 4:50] The global using directive composes with the using static form that was added earlier. The combination lets you drop the class prefix from a static class member across the entire project. The motivating case Tim shows is Console.WriteLine:
global using static System.Console;global using static System.Console;With that single line in the centralized usings file, Console.WriteLine("hello") becomes simply WriteLine("hello") everywhere in the project. The same pattern works for math helpers (global using static System.Math lets you write Sqrt(x) without the prefix) and for any other static class your codebase leans on heavily.
This is the form Tim is most cautious about. Dropping the class prefix is a readability gain when the methods are obvious, but it can become a source of confusion when two static classes expose methods with the same name. A reader looking at a bare WriteLine call has to trust the central file rather than seeing the source in context.
When Global Imports Step on Each Other
[4:50 - 5:14] The whole point of namespaces is to keep types with the same short name from colliding. Globally importing a namespace removes that buffer for the entire project at once. If your GlobalUsings.Data namespace contains a Data class and you also globally import System.Data, every file now has to disambiguate. The cost shows up not where the conflict happens but in any future file that gets caught between the two.
Tim's guidance is to use global usings deliberately, prefer namespaces you know the project depends on universally, and stay especially careful with global using static. A reasonable starting set is the namespaces every file imports anyway; growing the list past that calls for a code review.
Wrapping Up: Less Ceremony, Same Behavior
[5:14 - 5:33] Global usings are a small feature that pays off across the lifetime of a project. Every file that no longer carries five lines of redundant imports is a file that opens to the actual code faster, and an edit to a shared namespace happens in one place instead of dozens. The same care that goes into type aliases and the broader using family applies here: use it where the readability win is clear, and keep the central file small enough that the next developer can scan it in one glance.
Conclusion
[5:14 - 5:33] Global usings replace per-file using lines with project-wide directives, the global using static variant drops the class prefix from static member calls, and a single Usings.cs file at the project root is the convention that keeps it discoverable. The feature is opt-in and additive, so adopting it on an existing codebase is incremental.
Example Tip: When you turn on implicit usings via <ImplicitUsings>enable</ImplicitUsings> in your .csproj, the SDK automatically adds a curated set of global usings (like System, System.Linq, and System.Collections.Generic) without you writing them. Pair that with your own Usings.cs for project-specific imports and the top of every file gets noticeably shorter.
Watch full video on his YouTube Channel and gain more insights on modern C# project structure in the 10-Minute Training series.

