C# Standard Library
The C# standard library is the large set of ready-made types and methods that come with .NET. It matters because most real programs are built by combining your own code with library features for text, numbers, collections, files, networking, dates, tasks, exceptions, and much more.
In C#, people often say “standard library” when they mean the .NET Base Class Library, or BCL. You do not need to memorize it all, but you should understand how it is organized and which parts you will reach for every day.
Overview: How the Standard Library Works
C# is the language, but .NET supplies the runtime and most of the reusable APIs. The compiler turns your C# code into an assembly containing IL and metadata. At runtime, the CLR loads that assembly and also loads referenced library assemblies such as System.Private.CoreLib, System.Console, System.Linq, and System.Collections. Your code then calls methods on library types just like it calls your own methods.
The library is organized mainly by namespaces. A namespace is a logical name that groups related types. System contains fundamental types such as String, DateTime, Math, Console, Exception, and Guid. System.Collections.Generic contains strongly typed collections such as List<T>, Dictionary<TKey, TValue>, Queue<T>, and HashSet<T>. System.Linq adds query methods such as Where, Select, OrderBy, and Sum. System.IO handles files, directories, streams, readers, and writers.
A using directive does not copy library code into your file. It only lets the compiler resolve type names without writing their full namespace. For example, with using System.IO; you can write File.ReadAllText instead of System.IO.File.ReadAllText. The actual library code is still referenced from assemblies that your project depends on.
Modern .NET projects usually enable implicit global usings, so common namespaces may already be available. You should still know the real namespace because error messages, documentation, and API search results are organized around full type names such as System.Collections.Generic.Dictionary<TKey, TValue>.
The standard library favors types that are reusable across languages. C#, F#, Visual Basic, and other .NET languages can all call the same public APIs because they compile to compatible metadata. That is why C# aliases such as string, int, and bool map to CLR types: System.String, System.Int32, and System.Boolean.
Syntax
using NamespaceName;
NamespaceName.TypeName value = NamespaceName.TypeName.Member(arguments);
TypeName shorter = TypeName.Member(arguments);
| Part | Meaning |
|---|---|
using NamespaceName; |
Makes types in a namespace available by short name in this file. |
NamespaceName.TypeName |
The fully qualified type name. This always works when the assembly is referenced. |
TypeName.Member |
A static method, property, field, or nested type on a library type. |
new TypeName(...) |
Creates an instance of a library type when the type is not purely static. |
Common Namespace Reference
| Namespace | What you use it for |
|---|---|
System |
Fundamental types, console I/O, math, dates, exceptions, random numbers, GUIDs. |
System.Collections.Generic |
Typed lists, dictionaries, sets, queues, stacks, and collection interfaces. |
System.Linq |
Querying and transforming sequences. |
System.IO |
Files, directories, paths, streams, text readers, and text writers. |
System.Text |
StringBuilder, encodings, and text-related helpers. |
System.Threading.Tasks |
Task-based asynchronous programming. |
System.Net.Http |
HTTP clients and responses. |
Examples
Strings, Math, and Dates
using System;
using System.Globalization;
class Program
{
static void Main()
{
string name = " ada lovelace ";
string cleaned = CultureInfo.InvariantCulture.TextInfo.ToTitleCase(name.Trim());
double radius = 2.5;
double area = Math.PI * Math.Pow(radius, 2);
DateTime published = new DateTime(1843, 8, 1);
Console.WriteLine(cleaned);
Console.WriteLine($"Area: {area:F2}");
Console.WriteLine(published.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture));
}
}
Output:
Ada Lovelace
Area: 19.63
1843-08-01
This example uses library features from System and System.Globalization. string.Trim returns a new string without surrounding whitespace, TextInfo.ToTitleCase applies culture-aware casing rules, Math provides numeric helpers, and DateTime stores a date value. The format string keeps the output deterministic.
Collections and LINQ
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
class Program
{
static void Main()
{
List<Product> products = new List<Product>
{
new Product("Notebook", "Office", 4.50m),
new Product("Pencil", "Office", 1.25m),
new Product("Mug", "Kitchen", 8.00m)
};
var officeProducts = products
.Where(product => product.Category == "Office")
.OrderBy(product => product.Price)
.Select(product => .Select(product => $"{product.Name}: {product.Price:C}")quot;{product.Name}: ${product.Price.ToString("0.00", CultureInfo.InvariantCulture)}");
foreach (string line in officeProducts)
{
Console.WriteLine(line);
}
}
}
record Product(string Name, string Category, decimal Price);
Output:
Pencil: $1.25
Notebook: $4.50
List<T> stores strongly typed items in insertion order. LINQ extension methods then create a query pipeline. Where filters, OrderBy sorts, and Select projects each product into a display string. The query is deferred: it is not executed until the foreach asks for items.
Files and Dictionaries
using System;
using System.Collections.Generic;
using System.IO;
class Program
{
static void Main()
{
string path = Path.Combine(Path.GetTempPath(), "cs-library-demo.txt");
File.WriteAllLines(path, new[] { "red", "blue", "red" });
Dictionary<string, int> counts = new Dictionary<string, int>();
foreach (string color in File.ReadAllLines(path))
{
counts[color] = counts.GetValueOrDefault(color) + 1;
}
Console.WriteLine($"red={counts["red"]}");
Console.WriteLine($"blue={counts["blue"]}");
File.Delete(path);
}
}
Output:
red=2
blue=1
Path builds a valid path for the current operating system. File.WriteAllLines and File.ReadAllLines are convenient static methods for small text files. Dictionary<string, int> maps each color to a count, and GetValueOrDefault avoids a separate existence check for the first occurrence.
How It Works Step by Step
- You write code that names library types such as
List<T>,File, orDateTime. - The compiler resolves those names using your
usingdirectives, project references, and framework references. - The compiler emits IL instructions that call constructors, methods, properties, and extension methods from referenced assemblies.
- When the program starts, the CLR loads your assembly and the required framework assemblies.
- The JIT compiler translates the IL for executed methods into native machine code. Frequently used library code benefits from years of optimization in the runtime and framework.
- Some APIs allocate managed objects on the heap, some use value types on the stack or inside other objects, and some wrap operating-system resources such as files or sockets.
That last point is important. A string is immutable managed memory. A List<T> owns an internal array that grows as needed. A FileStream represents an external resource and should be disposed. Library types are not all the same; the documentation usually tells you whether a type is immutable, thread-safe, disposable, lazy, or culture-sensitive.
Common Mistakes
Assuming using Adds a Package
using SomeMissingPackage;
class Program
{
static void Main()
{
Console.WriteLine("Hello");
}
}
This does not compile unless a referenced assembly actually contains that namespace. A using directive only shortens names; it does not install a NuGet package or add a project reference. First add the reference, then use the namespace.
Forgetting That Some Library Methods Are Culture-Sensitive
using System;
using System.Globalization;
class Program
{
static void Main()
{
decimal price = 12.5m;
string stored = price.ToString(CultureInfo.InvariantCulture);
decimal parsed = decimal.Parse(stored, CultureInfo.InvariantCulture);
Console.WriteLine(stored);
Console.WriteLine(parsed == price);
}
}
Output:
12.5
True
Formatting numbers and dates with the current culture is correct for user interfaces, but it is risky for stored data, logs, and machine-readable text. Use CultureInfo.InvariantCulture when the text must mean the same thing on every computer.
Leaving Disposable Resources Open
using System;
using System.IO;
class Program
{
static void Main()
{
string path = Path.Combine(Path.GetTempPath(), "cs-library-using-demo.txt");
using (StreamWriter writer = new StreamWriter(path))
{
writer.WriteLine("closed automatically");
}
Console.WriteLine(File.ReadAllText(path).Trim());
File.Delete(path);
}
}
Output:
closed automatically
Streams, writers, readers, timers, HTTP responses, and many other library objects can hold unmanaged resources. If a type implements IDisposable or IAsyncDisposable, use a using statement or declaration so cleanup happens even when an exception is thrown.
Best Practices
- Learn the most common namespaces first:
System,System.Collections.Generic,System.Linq,System.IO,System.Text, andSystem.Threading.Tasks. - Prefer generic collections such as
List<T>andDictionary<TKey, TValue>over older non-generic collections. - Use LINQ for clear sequence transformations, but avoid hiding expensive repeated work inside long query chains.
- Use
StringBuilderwhen repeatedly appending text in loops; ordinary string concatenation creates new strings. - Use invariant culture for persisted machine-readable data and current culture for user-facing display.
- Dispose library objects that own external resources.
- Read API documentation for exceptions, null behavior, culture behavior, thread safety, and whether a method mutates or returns a new value.
- Prefer high-level APIs such as
File.ReadAllTextfor small simple jobs, and streams for large files or incremental processing.
Practice Exercises
- Create a program that stores five names in a
List<string>, filters names longer than four characters with LINQ, and prints them alphabetically. - Write a small word-count program that writes three lines to a temporary file, reads them back, and counts how many times each word appears.
- Format the same
decimalandDateTimevalue for display with the current culture and for storage withCultureInfo.InvariantCulture.
Summary
- The C# standard library usually means the .NET Base Class Library.
- Namespaces organize library types;
usingdirectives make those names shorter but do not add references. - Core APIs cover text, numbers, collections, files, dates, exceptions, tasks, networking, and diagnostics.
- The compiler emits calls to library assemblies, and the CLR loads and executes those assemblies at runtime.
- Generic collections, LINQ,
System.IO,Math,DateTime, and formatting APIs are daily-use tools. - Watch for culture-sensitive formatting, deferred LINQ execution, mutable collections, immutable strings, and disposable resources.
