Chapter 15 Csharp 8 And Beyond

2 min read
Mid-level2 min read
Rapid overview

Chapter 15 Csharp 8 And Beyond

TL;DR

Purpose of this chapter: understand the C# 8 feature set (and nearby future items) that meaningfully change how we write safe, expressive code: nullable reference types, switch expressions and richer patterns, ranges/indexes, and deeper async integration.

How it works


15.2 Switch expressions

Switch expressions make mapping logic concise and expression-oriented:

  • Great for “value in → value out” mappings.

Guideline:

  • Use when it improves clarity; don’t cram complex logic into a single expression if a statement-based switch is clearer.

15.3 Recursive pattern matching

Patterns can match deeper structure, not just top-level types.

15.3.1 Property patterns

Match based on property values (shape + constraints).

15.3.2 Deconstruction patterns

Match using Deconstruct shape.

15.3.3 Omitting types

Patterns can often infer types; use when it stays readable.


15.4 Indexes and ranges

Indexes/ranges make slicing more expressive:

  • ^1 means “from the end”.
  • a[1..^1] means a slice/range (excluding endpoints based on indices).

Guideline:

  • Great for parsing and data processing, but keep boundaries clear and test off-by-one behavior.

15.5 More async integration

15.5.1 Async disposal (await using)

Use for resources requiring async cleanup:

  • Important for I/O resources where disposal can be asynchronous.

15.5.2 Async iteration (await foreach)

Consume IAsyncEnumerable<T> streams without buffering everything in memory.

15.5.3 Async iterators

Produce async streams with async + yield return semantics (conceptually).

Interview angle:

  • These matter in high-throughput services for streaming data pipelines and backpressure-aware designs.

15.6 Features not yet in preview (book context)

The book discusses items that became real later (or evolved), e.g.:

  • Default interface methods
  • Records

Takeaway:

  • Know the “direction of travel”: safer types, richer patterns, and better async ergonomics.

15.7 Getting involved

Practical suggestion:

  • Track language proposals and adopt features deliberately; avoid churn without a payoff.

See also

Nullable reference types are about making nullability explicit in the type system so the compiler can warn about null mistakes.

15.1.1 What problem do they solve?

They reduce:

  • NullReferenceExceptions in production.
  • “Maybe null” ambiguity in APIs.

15.1.2 Changing meaning for reference types

With NRT enabled:

  • string typically means “non-null string”.
  • string? means “may be null”.

15.1.3 Enter NRT (compiler-assisted contracts)

The compiler tracks null-state flow:

  • It warns when you might dereference null.
  • It warns when you assign a maybe-null to a non-nullable reference.

15.1.4 Compile time vs runtime

Important: NRT is primarily a compile-time feature.

  • It doesn’t change runtime behavior of references (null still exists).

15.1.5 The “damn it” / bang operator (!)

x! means “I assert this isn’t null”.

Guideline:

  • Use sparingly; treat it as a localized escape hatch when you can prove invariants but the compiler can’t.

15.1.6 Migration experience

Practical approach:

  • Enable NRT in a controlled way, fix warnings in layers, add annotations to public APIs, and keep warning counts trending down.