Skip to content

Using Directives

A using directive imports a namespace so you can reference its types by their short name instead of the fully-qualified path. C# also has using statements (a different, unrelated meaning) for automatically disposing objects that hold unmanaged resources, and global using (C# 10+) to apply a using directive project-wide instead of per-file.

using System;
using System.Collections.Generic;
using System.Linq;
var numbers = new List<int> { 1, 2, 3 }; // List<T> available without System.Collections.Generic.List<T>
var evens = numbers.Where(n => n % 2 == 0); // Where() available via System.Linq
// using ALIAS -- give a namespace or type a shorter/different name
using Json = System.Text.Json.JsonSerializer;
var text = Json.Serialize(numbers);
// using STATEMENT -- automatically disposes the object at the end of the block
using (var file = new StreamReader("data.txt"))
{
string content = file.ReadToEnd();
} // file.Dispose() called automatically here, even if an exception occurs
// global using (in a shared file, C# 10+) -- applies to every file in the project
// global using System;

Confusing the using directive (imports a namespace) with the using statement (disposes a resource) β€” they share a keyword but do completely unrelated things, which trips up developers new to C#.

// This is a DIRECTIVE -- import System.IO's types
using System.IO;
// This is a STATEMENT -- dispose `file` when the block ends
using (var file = new StreamReader("data.txt"))
{
// ...
}
// Easy to misread which one you're looking at without context
  1. What’s the difference between a using directive and a using statement?

    AnswerA using directive (at the top of a file, like using System;) imports a namespace; a using statement (using (var x = ...) { }) automatically calls Dispose() on an object when the block ends.
  2. What does global using (C# 10+) let you do?

    AnswerApply a using directive across the entire project from one shared file, instead of repeating the same imports at the top of every individual file.
  3. What guarantee does a using statement give you that manually calling Dispose() doesn’t?

    AnswerIt calls Dispose() automatically even if an exception is thrown inside the block, whereas a manual Dispose() call at the end of a method would be skipped if an earlier line throws.