Base class library
The .NET Base Class Library (BCL) is the standard library that ships with every .NET installation. It is substantially larger than C++‘s standard library or C’s: it covers strings, collections, LINQ, files and streams, networking, cryptography, JSON and XML, regular expressions, reflection, threading and tasks, and a substantial set of utility types. The library’s surface is too large to enumerate exhaustively; this page surveys the principal namespaces and provides routes to the in-depth treatment, with the goal of making the BCL navigable rather than completely documented.
The BCL is the single largest practical advantage of C# over languages with smaller standard libraries: most application code can be written using only the BCL plus a small number of NuGet packages, and the conventions for using each part of the BCL are well-established.
The BCL structure
The BCL is organised under the System namespace and its descendants. The principal divisions:
| Namespace | Purpose |
|---|---|
System | Fundamental types: primitives, exceptions, basic conversions |
System.Collections (legacy) | Non-generic collections (rarely used in new code) |
System.Collections.Generic | The standard generic collections |
System.Collections.Concurrent | Thread-safe collections |
System.Collections.Immutable | Persistent collections |
System.Linq | LINQ operators |
System.IO | File and stream I/O |
System.Text | Text encoding and string building |
System.Text.RegularExpressions | Regex |
System.Text.Json | JSON serialisation |
System.Xml | XML processing |
System.Net | Networking primitives |
System.Net.Http | HTTP client |
System.Threading | Threading primitives |
System.Threading.Tasks | Tasks and async |
System.Diagnostics | Logging, tracing, profiling |
System.Reflection | Type and member introspection |
System.Runtime.InteropServices | Native interop |
System.Security.Cryptography | Cryptographic primitives |
System — fundamental types
The System namespace contains:
- The numeric types:
Int32,Int64,Double,Decimal, etc. (each aliased by a C# keyword). String,Object,Type,Array.DateTime,DateTimeOffset,TimeSpan,DateOnly(.NET 6+),TimeOnly(.NET 6+).Guidfor globally unique identifiers.Tuple<T1, …>andValueTuple<T1, …>.- The base exception types (
Exception,ArgumentException,InvalidOperationException, etc.). Consolefor standard input/output.MathandMathFfor math functions.Convertfor type conversions.Randomfor pseudo-random numbers.Environmentfor process and OS information.
using System;
DateTime now = DateTime.Now;
Guid id = Guid.NewGuid();
double pi = Math.PI;
double sq = Math.Sqrt(2.0);
int n = Random.Shared.Next(0, 100); // .NET 6+
Random.Shared (.NET 6+) is a thread-safe shared instance; the conventional contemporary entry point for ad-hoc random numbers.
System.Collections.Generic — the standard collections
Treated in LINQ. The principal types:
List<T>— dynamic array.Dictionary<TKey, TValue>— hash table.HashSet<T>— hash set.SortedDictionary<TKey, TValue>— red-black tree.SortedSet<T>— red-black tree.Queue<T>,Stack<T>,LinkedList<T>.PriorityQueue<TElement, TPriority>(.NET 6+) — binary-heap priority queue.
System.Linq — LINQ
Treated in LINQ.
System.IO — files and streams
Treated in I/O and streams. The principal types:
Streamand its derivatives:FileStream,MemoryStream,NetworkStream,BufferedStream.StreamReader,StreamWriter,BinaryReader,BinaryWriter.File,Directory,Pathfor filesystem operations.FileInfo,DirectoryInfofor object-oriented filesystem access.FileSystemWatcherfor filesystem change notifications.
System.Text and System.Text.RegularExpressions
System.Text provides:
StringBuilderfor mutable string construction.Encoding,UTF8Encoding,UnicodeEncoding,ASCIIEncodingfor byte ↔ text conversion.Rune(.NET Core 3+) for Unicode code points.CompositeFormat(.NET 8+) for compiled format strings.
using System.Text;
var sb = new StringBuilder();
sb.Append("hello").Append(", ").Append(42);
string s = sb.ToString();
byte[] utf8 = Encoding.UTF8.GetBytes("Hello, 世界");
string back = Encoding.UTF8.GetString(utf8);
System.Text.RegularExpressions provides regex:
using System.Text.RegularExpressions;
var regex = new Regex(@"\d{4}-\d{2}-\d{2}");
Match m = regex.Match(input);
if (m.Success) {
Console.WriteLine($"matched: {m.Value} at {m.Index}");
}
foreach (Match match in regex.Matches(text)) {
/* each match */
}
string replaced = regex.Replace(text, "REDACTED");
C# 11 introduced source-generated regex — compile-time-generated regex implementations:
public partial class Validator {
[GeneratedRegex(@"\d{4}-\d{2}-\d{2}")]
private static partial Regex DateRegex();
public bool IsDate(string s) => DateRegex().IsMatch(s);
}
The mechanism is faster than the conventional new Regex(...) because the compiler generates the regex implementation at build time.
System.Net.Http — HTTP client
HttpClient is the conventional HTTP client:
using System.Net.Http;
using var client = new HttpClient();
HttpResponseMessage response = await client.GetAsync("https://example.com/data");
response.EnsureSuccessStatusCode();
string body = await response.Content.ReadAsStringAsync();
The conventional discipline:
- Reuse
HttpClientinstances (do not create one per request); the connection pool benefits from reuse. - Use
IHttpClientFactory(in dependency-injected applications) for managedHttpClientinstances. - Always
EnsureSuccessStatusCode()or checkIsSuccessStatusCodebefore consuming the body. - Pass
CancellationTokenfor cancellation.
System.Text.Json, System.Xml
System.Text.Json is the conventional JSON serialiser:
using System.Text.Json;
var person = new { Name = "alice", Age = 30 };
string json = JsonSerializer.Serialize(person);
// {"Name":"alice","Age":30}
var parsed = JsonSerializer.Deserialize<Person>(json);
The serialiser is fast and supports source-generated serialisation for AOT scenarios:
[JsonSerializable(typeof(Person))]
public partial class PersonContext : JsonSerializerContext { }
string json = JsonSerializer.Serialize(person, PersonContext.Default.Person);
The conventional contemporary alternative to JSON serialisation libraries is System.Text.Json; the older Newtonsoft.Json (Json.NET) remains widely used in legacy code.
For XML, System.Xml.Linq (LINQ to XML) is the conventional choice:
using System.Xml.Linq;
XDocument doc = XDocument.Load("config.xml");
foreach (XElement node in doc.Descendants("item")) {
Console.WriteLine(node.Attribute("id")?.Value);
}
System.Xml (the older XML stack) provides the lower-level XmlReader and XmlWriter for streaming XML, and XmlDocument (the DOM-style API) for older code.
System.Threading, System.Threading.Tasks
Treated in Async and concurrency. The principal types:
Thread,ThreadStart.Task,Task<T>.ValueTask,ValueTask<T>.CancellationToken,CancellationTokenSource.SemaphoreSlim,Mutex,Barrier,CountdownEvent.Parallelfor parallel loops.ManualResetEventSlim,AutoResetEvent.Interlockedfor atomic operations.
System.Diagnostics
The diagnostics namespace provides:
Stopwatchfor timing measurements.Processfor process management.TraceandDebugfor diagnostic output.Activityfor distributed-tracing context propagation.Stopwatch,EventCounter,Meterfor performance counters.
using System.Diagnostics;
var sw = Stopwatch.StartNew();
DoWork();
sw.Stop();
Console.WriteLine($"elapsed: {sw.ElapsedMilliseconds} ms");
Debug.Assert(condition, "must hold");
Debug.WriteLine("diagnostic info");
Debug.Assert and Debug.WriteLine compile to nothing in release builds (when DEBUG is not defined); the runtime cost is zero in production.
System.Reflection
The reflection API exposes runtime type information:
using System.Reflection;
Type t = typeof(SomeClass);
MethodInfo[] methods = t.GetMethods();
PropertyInfo[] properties = t.GetProperties();
foreach (var p in properties) {
Console.WriteLine($"{p.Name}: {p.PropertyType}");
}
// Invoke a method by name:
MethodInfo? mi = t.GetMethod("DoSomething");
mi?.Invoke(instance, new object[] { 42 });
The principal uses are serialisation, dependency injection, ORM mapping, and dynamic dispatch. The conventional contemporary alternatives are source generators (compile-time code generation), which are faster than reflection and AOT-friendly.
System.Span<T>, System.Memory<T>
The Span<T> and Memory<T> types provide non-allocating views over contiguous memory:
ReadOnlySpan<byte> data = SomeBuffer();
ReadOnlySpan<byte> slice = data.Slice(0, 10);
Span<byte> output = stackalloc byte[256];
int written = ProcessBytes(data, output);
The treatment is in Memory and the CLR.
System.Numerics
System.Numerics provides:
BigInteger— arbitrary-precision integers.Complex— complex numbers.Vector<T>,Vector2,Vector3,Vector4— SIMD-friendly vector types.Matrix3x2,Matrix4x4,Quaternion,Plane— graphics-oriented math.
using System.Numerics;
BigInteger fact100 = Enumerable.Range(1, 100).Aggregate(BigInteger.One, (acc, x) => acc * x);
Vector3 sum = new Vector3(1, 2, 3) + new Vector3(4, 5, 6);
.NET 7+ added generic math (INumber<T>, IAdditionOperators<T, T, T>, etc.), which admits writing generic numeric algorithms.
System.Globalization
CultureInfo represents a locale; CultureInfo.CurrentCulture, CultureInfo.InvariantCulture, and CultureInfo.GetCultureInfo("en-US") provide instances:
using System.Globalization;
double d = 3.14;
string s = d.ToString(CultureInfo.InvariantCulture); // "3.14"
string s2 = d.ToString(new CultureInfo("de-DE")); // "3,14"
DateTime parsed = DateTime.Parse("3/14/2024", CultureInfo.GetCultureInfo("en-US"));
The conventional discipline: use CultureInfo.InvariantCulture for programmatic formatting and parsing; use the user’s CurrentCulture for user-facing display.
System.Random, System.Security.Cryptography.RandomNumberGenerator
Random is the pseudo-random generator; Random.Shared (.NET 6+) is the thread-safe shared instance:
int n = Random.Shared.Next(0, 100);
For cryptographic randomness, RandomNumberGenerator:
using System.Security.Cryptography;
byte[] bytes = new byte[16];
RandomNumberGenerator.Fill(bytes);
The conventional discipline: Random for non-security random numbers; RandomNumberGenerator for tokens, keys, salts, anything security-sensitive.
System.Security.Cryptography
Symmetric and asymmetric cryptography:
using System.Security.Cryptography;
// Hashing:
byte[] hash = SHA256.HashData(Encoding.UTF8.GetBytes("hello"));
// HMAC:
using var hmac = new HMACSHA256(key);
byte[] mac = hmac.ComputeHash(message);
// Symmetric encryption:
using var aes = Aes.Create();
aes.Key = key;
aes.IV = iv;
byte[] ciphertext = aes.EncryptCbc(plaintext, iv);
The library covers SHA-256/SHA-384/SHA-512, AES, ChaCha20-Poly1305 (.NET 5+), RSA, ECDSA, Ed25519 (.NET 7+), PBKDF2, Argon2 (.NET 9+).
Microsoft.Extensions.* — the dependency-injection ecosystem
Beyond the BCL proper, the Microsoft.Extensions namespaces provide infrastructure for modern .NET applications:
| Namespace | Purpose |
|---|---|
Microsoft.Extensions.DependencyInjection | Dependency-injection container. |
Microsoft.Extensions.Configuration | Configuration from JSON, environment, etc. |
Microsoft.Extensions.Logging | Logging abstractions. |
Microsoft.Extensions.Hosting | Hosted-service infrastructure. |
Microsoft.Extensions.Options | Strongly-typed configuration options. |
These are not strictly part of the BCL — they ship as separate NuGet packages — but they are universal in modern .NET applications. Most application templates include them out of the box.
A note on the larger .NET ecosystem
Beyond the BCL and Microsoft.Extensions.*:
- ASP.NET Core — web frameworks, MVC, Razor Pages, Minimal APIs, Blazor, SignalR, gRPC.
- Entity Framework Core — ORM with LINQ-based queries.
- MAUI — cross-platform UI for desktop and mobile.
- WPF, Windows Forms — Windows-only desktop UI.
- Xamarin — predecessor to MAUI; legacy.
- AutoMapper, Mapster — object mapping.
- Polly — resilience (retry, circuit breaker).
- Serilog, NLog — logging providers.
- xUnit, NUnit, MSTest — testing frameworks.
- FluentAssertions — fluent test assertions.
- Moq, NSubstitute — mocking libraries.
- Akka.NET — actor-model concurrency.
- Hangfire, Quartz.NET — background-job processing.
The conventional advice: start with the SDK templates (dotnet new); add NuGet packages as needed; rely on the BCL for fundamentals and the broader ecosystem for higher-level concerns.