C# 15 Extension Indexers: Add [] Syntax to Types You Don't Own
C# 15 lets you declare indexers inside extension blocks, so types you don't own can support square-bracket access. Adding Count and Slice also unlocks index-from-end, ranges, and list patterns. The feature was tested on the .NET 11 RC 1 SDK, and the article lists its gotchas: real indexers win silently, arrays and strings are excluded, and expression trees reject it.
Key points
- C# 15 allows this[...] indexers inside extension blocks and ships with .NET 11.
- Adding Count, an integer indexer and Slice enables ^1, ranges and list patterns.
- A type's real indexer always wins over an extension, with no compiler warning.
- Arrays and strings are not covered: an extension indexer on int[] fails with CS0029.
- Extension indexers cannot be used in expression trees (CS9296), which affects EF Core queries.
- On .NET 10 and C# 14 the feature is preview and gives error CS8652.
C# 15, shipping with .NET 11, lets you declare this[...] inside an extension block, so a wrapper type or an interface such as IReadOnlyDictionary can be read with square brackets instead of a helper method. The author tested this on the .NET 11 RC 1 SDK without any LangVersion setting, and notes that C# 14 added extension properties but left indexers out. This release closes that gap.
The bigger payoff comes when you add a Count member and an integer indexer, together with a Slice method. The compiler then treats the type as a countable collection, which enables index-from-end, range expressions and list patterns with no extra code. There are limits to keep in mind: a type's own indexer always takes precedence over an extension, arrays and strings are excluded from this lookup, and extension indexers cannot appear in expression trees, which matters for EF Core queries. Check the original for the full examples.
Real-world use
- Replacing GetAt-style helper methods on a third-party wrapper type with square-bracket access.
- Adding a default-value lookup such as map[key, fallback] to read-only dictionary interfaces.
- Exposing a grid or matrix type with row and column indexers that hide the index arithmetic in one place.
Why it matters
You can give types you don't own the familiar square-bracket syntax instead of maintaining per-type helper methods. Keep in mind that brackets can hide costly enumeration on lazy sequences, and the feature does not work inside expression trees such as EF Core queries.
Related stories
- Collection Return Types in C#: Interfaces, Views, and SnapshotsNick Cosentino (Dev Leader)2 d ago
- Dynamic Gauss-Legendre numerical integration in C#: computing nodes and weights on the fly without overflowHabr C# (ru)2 d ago
- Events and Delegates in C#: Contracts, Subscriptions and NotificationNick Cosentino (Dev Leader)3 d ago