Extension members C# 14.0 added extension properties, methods and operators but left out indexers.
C# 15 completes the set by allowing indexers to be declared in an extension block so you can index into a type as though the indexer were declared on it.
Code
csharp
IEnumerable<int> numbers = Enumerable.Range(1, 10);
int third = numbers[2];
public static class SequenceIndexer
{
extension(IEnumerable<int> sequence)
{
public int this[int index] => sequence.ElementAt(index);
}
}csharp
IEnumerable<int> numbers = Enumerable.Range(1, 10);
int third = numbers.GetAt(2);
public static class SequenceExtensions
{
public static int GetAt(this IEnumerable<int> sequence, int index) => sequence.ElementAt(index);
}Notes
- Indexers are always instance members so the
extensionblock must declare a named receiver parameter - Indexers declared on the type itself always win; extension indexers are only considered when none of the type's own indexers apply
- Indexer syntax looks cheap but this one calls
ElementAt, which can walk the sequence and be O(n) for sources that aren't lists