DEV Community

Cristian Sifuentes
Cristian Sifuentes

Posted on

Mastering Extension Members in C# 14 — Beyond Extension Methods

MasteringExtensionMembersInCSharp14

C# 14 introduces a powerful enhancement to the concept of extension methods: extension members. This feature allows you to extend not just instance methods, but also properties, indexers, and even static members of a type — with cleaner, more expressive syntax.

In this post, we’ll explore:

  • What extension members are
  • How to declare and use them
  • The difference between instance and static extension members
  • A real-world example
  • When and why to use them

Motivation — From Extension Methods to Extension Members

Before C# 14, we could only extend types with methods using static classes:

public static class StringExtensions
{
    public static bool IsNullOrWhiteSpace(this string str)
        => string.IsNullOrWhiteSpace(str);
}
Enter fullscreen mode Exit fullscreen mode

Useful? Yes. But limiting — no properties, no indexers, no static-style access. C# 14 changes that with a new syntax: extension<>().


Syntax Breakdown

Here’s the new structure in C# 14:

public static class Enumerable
{
    extension<TSource>(IEnumerable<TSource> source)
    {
        // Instance-like extension members here
    }

    extension<TSource>(IEnumerable<TSource>)
    {
        // Static-like extension members here
    }
}
Enter fullscreen mode Exit fullscreen mode

Now let’s walk through a complete example 👇


Example – Extending IEnumerable with Powerful Additions

public static class Enumerable
{
    // 🔹 Instance-style extension members
    extension<TSource>(IEnumerable<TSource> source)
    {
        // ✅ Extension Property
        public bool IsEmpty => !source.Any();

        // ✅ Extension Indexer
        public TSource this[int index] => source.Skip(index).First();

        // ✅ Extension Method
        public IEnumerable<TSource> Filter(Func<TSource, bool> predicate)
            => source.Where(predicate);
    }

    // 🔸 Static-style extension members
    extension<TSource>(IEnumerable<TSource>)
    {
        // ✅ Static Extension Method
        public static IEnumerable<TSource> Combine(IEnumerable<TSource> first, IEnumerable<TSource> second)
            => first.Concat(second);

        // ✅ Static Extension Property
        public static IEnumerable<TSource> Identity => System.Linq.Enumerable.Empty<TSource>();
    }
}
Enter fullscreen mode Exit fullscreen mode

How to Use It

var numbers = new[] { 10, 20, 30 };

// Instance-style usage
bool empty = numbers.IsEmpty;                   // 🔹 false
int second = numbers[1];                        // 🔹 20
var evens = numbers.Filter(n => n % 2 == 0);    // 🔹 {10, 20, 30}

// Static-style usage
var zeros = Enumerable<int>.Identity;           // 🔸 Empty sequence of int
var combined = Enumerable<int>.Combine(new[] { 1 }, new[] { 2 }); // 🔸 {1, 2}
Enter fullscreen mode Exit fullscreen mode

Behind the Scenes – What’s Really Happening?

C# 14 internally rewrites these extension blocks into static methods behind the scenes, just like regular extension methods, but the syntax sugar allows:

  • Properties with =>
  • Indexers using [index]
  • Static-style access without utility class noise
  • Stronger IDE support and IntelliSense

Best Use Cases

Scenario Why Extension Members Help
Fluent LINQ-style APIs Add expressive filters, transforms, summaries
DSL for collections Indexers, state introspection (IsEmpty, IsSorted, etc.)
Static factories/utilities Return Empty, Singleton, or default prebuilt objects
Domain-driven design patterns Model behaviors tied to interfaces without modifying them

Notes & Tips

  • Only available in C# 14+ with .NET 10 SDK or higher.
  • Must be placed inside a static class.
  • Static extension members must use the type receiver, not an instance.
  • IntelliSense automatically differentiates between static and instance extension members.

Learn More


Final Thoughts

C# 14’s extension members open the door to expressive, modular, and scalable designs. Whether you're building LINQ-like utilities, extending existing APIs, or designing fluent interfaces, this feature makes your code more elegant and natural.

Start refactoring your extension utils into structured extension blocks today!


✍️ _Written by: [Cristian Sifuentes] - C# Architect | .NET Engineer |

📩 Got questions or ideas? Leave a comment or DM!

Top comments (0)