Course · 46 lessons

Modern C#

Model values, handle missing data, and express intent with modern C#.

  1. Records and value equality

    Describe a value with a record and compare its contents.

    Core ideas · 10 min
  2. Nullable values

    Represent an absent measurement without inventing a number.

    Core ideas · 10 min
  3. Property patterns

    Choose a result from several fields of a value.

    Core ideas · 10 min
  4. Switch expressions

    Return one value from an exhaustive set of cases.

    Core ideas · 10 min
  5. Tuples and deconstruction

    Return two related results without an output parameter.

    Working with data · 10 min
  6. Init-only properties

    Construct a value and restrict later assignment.

    Working with data · 10 min
  7. Generic methods

    Preserve a caller’s type through reusable logic.

    Working with data · 10 min
  8. Interface contracts

    Call different implementations through one useful contract.

    Working with data · 10 min
  9. Value copies and references

    Predict whether assignment copies data or shares an object.

    Putting it together · 10 min
  10. Iterator methods

    Produce sequence elements when a consumer requests them.

    Putting it together · 10 min
  11. Flags and explicit checks

    Combine independent options and test whether one is present.

    Putting it together · 10 min
  12. Validation as a result

    Make expected input failures visible in a method contract.

    Putting it together · 10 min
  13. Guard clauses and precise exceptions

    Reject invalid inputs before they reach the main calculation.

    Deeper practice · 18 min
  14. Required members are a construction contract

    Separate compiler-enforced initialization from runtime validation.

    Deeper practice · 18 min
  15. Record copies and shared collections

    Inspect equality and mutation when records contain reference members.

    Deeper practice · 18 min
  16. Readonly record structs and value copies

    Use small immutable values without confusing them with shared objects.

    Deeper practice · 18 min
  17. Defensive copies at ownership boundaries

    Keep a caller-owned array from rewriting an established snapshot.

    Deeper practice · 18 min
  18. Virtual behavior through a base reference

    Follow runtime dispatch while keeping the public contract stable.

    Deeper practice · 18 min
  19. Strategy functions with delegates

    Pass a calculation policy instead of duplicating an entire workflow.

    Deeper practice · 18 min
  20. Generic constraints express capabilities

    Require comparison explicitly before writing a generic minimum.

    Deeper practice · 18 min
  21. Covariant read-only views

    Read derived values through a base interface without promising writes.

    Applied techniques · 18 min
  22. Explicit interface implementations

    Resolve two contracts without making their meanings ambiguous.

    Applied techniques · 18 min
  23. Exception filters preserve diagnostic distinctions

    Handle one expected failure while letting unrelated failures remain visible.

    Applied techniques · 18 min
  24. Deterministic cleanup with using

    Release an owned resource when control leaves its scope.

    Applied techniques · 18 min
  25. List patterns describe sequence shapes

    Recognize an array shape before reading its selected elements.

    Applied techniques · 18 min
  26. Ranges and spans without new array storage

    Read a portion of a buffer while respecting shared lifetime and mutation.

    Applied techniques · 18 min
  27. Extension methods remain ordinary static behavior

    Add a readable operation without changing the represented type.

    Applied techniques · 18 min
  28. Closures capture variables, not frozen values

    Predict a delegate after the state it references changes.

    Applied techniques · 18 min
  29. Collection expressions need a target

    Choose array, list, and read-only interface targets deliberately.

    Current C# & .NET · 12 min
  30. Spread elements materialize a sequence

    Track spread enumeration and distinguish a shallow snapshot from a live query.

    Current C# & .NET · 12 min
  31. Primary constructors in ordinary classes

    Use a primary-constructor parameter without assuming record properties.

    Current C# & .NET · 12 min
  32. Aliases name tuple and array types

    Separate source-level aliases from new nominal types or copied storage.

    Current C# & .NET · 12 min
  33. Generic math through static contracts

    Call numeric identities and operators through INumber<T> constraints.

    Current C# & .NET · 12 min
  34. Params collections without an array contract

    Accept a C# 13 params ReadOnlySpan<int> with empty and existing-array cases.

    Current C# & .NET · 12 min
  35. FrozenDictionary fixes lookup policy

    Freeze a read-heavy map with an explicit comparer and detached scalar values.

    Current C# & .NET · 12 min
  36. SearchValues reuses a search set

    Find any separator with a reusable search set and explicit not-found handling.

    Current C# & .NET · 12 min
  37. C# 14 extension blocks and properties

    Compare an ordinary helper with a real extension-property project for .NET 10.

    C# 14 / .NET 10 — external projects · 15 min
  38. C# 14 field-backed property validation

    Compare explicit backing storage with a real field-keyword accessor.

    C# 14 / .NET 10 — external projects · 15 min
  39. C# 14 null-conditional assignment

    Observe conditional right-side evaluation with guards and a real C# 14 project.

    C# 14 / .NET 10 — external projects · 15 min
  40. C# 14 nameof accepts unbound generics

    Distinguish a compile-time display name from reflection type identity.

    C# 14 / .NET 10 — external projects · 15 min
  41. C# 14 span conversions at call boundaries

    Compare explicit span calls with generic extension receiver conversions.

    C# 14 / .NET 10 — external projects · 15 min
  42. C# 14 inferred lambda parameter modifiers

    Keep a real out-parameter delegate while omitting redundant types externally.

    C# 14 / .NET 10 — external projects · 15 min
  43. C# 14 partial constructors and events

    Compare one complete type with defining and implementing declarations.

    C# 14 / .NET 10 — external projects · 15 min
  44. C# 14 user-defined compound assignment

    Observe in-place reference mutation separately from replacement addition.

    C# 14 / .NET 10 — external projects · 15 min
  45. .NET 10 file-based apps and build directives

    Run an actual SDK-managed single-file app externally; compare its domain rule here.

    C# 14 / .NET 10 — external projects · 15 min
  46. C# 13 ref-struct scope before await

    Finish span work before suspension and carry an ordinary result forward.

    Current C# & .NET · 12 min