C# evolution timeline

Walk from the .NET Framework 3.5 foundations into modern C# and see which guides define each runtime era.

Browse all features → · Browse by C# version → · Browse by theme →

NETFx 3.5 · Foundations for fluent C#

The early LINQ era brought query syntax, type inference, and concise object shaping into everyday C#.

NETFx 4.5 · Async-ready application code

Asynchronous workflows and cleaner APIs made application code easier to scale without losing readability.

NETFx 4.6 · Readable everyday syntax

String interpolation, expression-bodied members, and exception filters sharpened common code paths.

NETFx 4.7 · Local structure and lightweight data

Local functions, tuple-friendly code, and ref returns made everyday methods more expressive.

NETCore 2.1 · Performance-focused C#

The first big performance wave added spans, ref structs, and richer parameter passing for tighter control.

NETCore 3.0 · Safer APIs and richer interfaces

C# leaned into null-safety, cleaner resource handling, and interface evolution without sacrificing compatibility.

Range and index operators

C# 8.0 NETCore 3.0

Range (…) and index (^) operators provide concise syntax for accessing array elements and extracting subsequences. The index operator lets you count from the end; the range operator extracts contiguous slices without manual offset calculations.

Read full guide →

.NET 5.0 · Modern modeling and branching

Records, init accessors, switch expressions, and pattern matching pushed C# toward concise domain modeling.

.NET 6.0 · Lean files and startup paths

File-scoped namespaces, global usings, and top-level statements trimmed ceremony from modern apps.

.NET 7.0 · Compile-time guardrails

List patterns, raw strings, required members, and generic math continued the move toward safer expressive code.

.NET 8.0 · Latest concise modeling

Primary constructors and collection expressions keep modern C# compact, direct, and ready for current codebases.