C# 14 Extension Members: Extension Properties, Static Members and Operators
C# 14, shipped with .NET 10, adds extension members: extension properties, static members and operators declared inside extension blocks. This goes beyond the classic this-parameter extension methods and lets APIs read more naturally. Knowing the current limits, such as no state and no indexers, matters before adopting it in production.
Key points
- An extension(Type receiver) { ... } block declares the receiver once, and every member inside uses it.
- Extension properties can replace older GetX()-style helper methods with computed properties.
- A block without a parameter name (extension(Currency)) allows static extension members and operators.
- Blocks cannot declare fields or auto-implemented properties, so caches belong in the enclosing static class.
- Indexers are only a preview in the .NET 10 compiler, and events are not supported.
- Classic this methods keep working alongside the new blocks, so migration can be gradual.
Extension methods, introduced in C# 3.0 mainly to support LINQ, have for nearly two decades been limited to instance methods taking a this parameter. C# 14 on .NET 10 introduces extension blocks: a block declares the receiver type once, and the properties, static members and operators inside it operate on that type. This lets a type you do not own gain computed properties that read like its own members.
The blocks still sit inside a static class, so older this-style methods and new members can coexist, which makes gradual migration practical. There are limits, though. A block cannot hold fields or auto-implemented properties, events are not supported, and indexers are only a preview feature in the .NET 10 compiler. Dispatch is still resolved at compile time. The author's guidance is to reserve properties for cheap, side-effect-free values and use methods for work that does something.
Real-world use
- Exposing computed values such as an order total or shippable flag as properties on a model you do not own.
- Adding static factory members or operators to a third-party type without breaking its existing API.
- Gradually migrating a large codebase from this-style extension methods to extension blocks.
Why it matters
Extension members let C# 14 code expose more readable APIs, but the limits on state, events and dispatch mean you should consciously choose between property and method for each member.