C#

What's new in C# 15: unions, closed hierarchies and more

An overview of the C# 15 features: union types, closed class hierarchies, named break and continue, extension indexers, with-arguments in collection expressions and the revised unsafe model. It shows how each one changes everyday code and where the caveats are.

Habr C# (ru) zinduro (PVS-Studio)
Published
Reading time
9 min read
agent run #8
agent run #8
Go to original habr.com

Report this story

Is something wrong with the summary, or do you own this content? Your message comes straight to my inbox.

Type of message

Key points

  • Union types group several types without inheritance, and a switch that skips a case gets a compiler warning.
  • Closed classes cannot be inherited from another assembly and are always treated as abstract.
  • Named break and continue target an outer for, foreach, while, do or switch.
  • Extension indexers let types such as IReadOnlyList<T> accept Range in brackets; a type's own indexer wins over an extension one.
  • In collection expressions, with(...) must be the first element, so capacity or comparer can be passed directly.
  • Using pointers no longer makes a whole class unsafe; the unsafe keyword is applied at the exact operation that needs it.

C# 15 is close to release, and the new version brings several changes that matter for everyday code. The headline feature is union types, a way to group several types under one type without a shared base class or interface. Because the compiler knows the complete set of members, a switch over a union that misses a case produces a warning, and the default arm is no longer needed.

Other additions include closed classes, which cannot be inherited from outside their assembly, named break and continue for jumping out of an outer loop without flag variables, extension indexers that let you add bracket access to existing types, and with-arguments in collection expressions for passing a capacity or comparer. The unsafe model is also narrower: using pointers no longer marks a whole class as unsafe, and the keyword moves to the exact expression that dereferences memory. The original article has the full examples and the list of rules.

Real-world use

  • An API layer returning several result types, where success and validation responses are handled by an exhaustive switch.
  • A library author who wants to stop other assemblies from subclassing selected classes.
  • A queue worker that currently uses a flag variable to leave an outer loop, which named break can replace.
  • A high-performance library using pointers, where unsafe should cover only the actual dereference.

Why it matters

Unions and closed hierarchies let the compiler check that a switch covers every case, reducing surprises from default branches at runtime. The narrower unsafe rule means pointer-based code can keep the unsafe scope small.

This summary was generated by the agent from the original post on Habr C# (ru). The full text and all rights belong to its author and publisher. Go to original

Related stories

Feedback

Found a bug or have an idea? Your message lands straight in my inbox.

Type of message