C# 8.0 shipped with .NET Core 3.0 in September 2019. The feature set is more impactful than any C# release since C# 5.0 introduced async/await.
Nullable reference types
Nullable reference types (NRT) make the null-safety of reference types explicit in the type system. With NRT enabled, string is non-nullable (cannot be null without a compiler warning); string? is nullable. The compiler warns when a nullable value is used without a null check and when a non-nullable variable is assigned a potentially null value. Enabling NRT on existing codebases surfaces hundreds of implicit nullability assumptions that are potential NullReferenceExceptions.
Switch expressions
Switch expressions replace verbose switch statements with concise expression syntax. The arms of a switch expression use pattern matching: type patterns, property patterns, tuple patterns, and positional patterns. The switch expression is an expression (has a value) rather than a statement, enabling its use in property initialisers, ternary expressions, and LINQ. The pattern matching capability makes discriminated union-style code natural in C#.
Async streams
Async streams (IAsyncEnumerable
Ranges and indices
The index-from-end operator (^) and range operator (..) enable concise slice syntax for arrays and spans: array[^1] is the last element, array[1..^1] is all elements except first and last. The System.Range and System.Index types make this work with any indexable type that implements the required pattern. Combined with Span