NDepend Blog

Improve your .NET code quality with NDepend

C# 14 Extension Members: Also Known as Extension Everything

August 4, 2025 4 minutes read

C# 14 introduces extension members — also known as extension everything.

The New C# 14 Extension Method Syntax

The example below demonstrates how to migrate a traditional extension method using the this keyword to the new extension member syntax.

A few remarks:

  • If the extension is generic, the type parameter (if any) is specified immediately after the extension keyword.
  • The receiver ReadOnlySpan<T> span applies to one or more extension methods (or members) declared within the same extension block. This logical grouping is a core advantage of the new syntax, improving clarity and structure when extending a type.
  • As far as the C# compiler is concerned, the two methods Truncate() are strictly equivalent. Therefore, one must be commented out for the program to compile.
  • Notice the call to AsSpan() in the first line. Extension methods require the receiver type to match exactly ReadOnlySpan<T>, hence it doesn’t apply to string unless you explicitly cast. This is not specific to the new syntax but worth mentioning.

C# 14 Extension Everything

Extension everything embraces not only methods, but also extension properties and static extensions. I’ve always found the extra parentheses in calls like str.IsEmpty() a bit awkward for something that conceptually feels like a property.

Also extension operators have already been implemented and are expected to be available in .NET 10 Preview 7.

Here is a code sample demonstrating both extension properties and static extensions:

Notice that extension properties are not necessarily read-only. A setter can also be declared:

Decompiling Extension Everything

By decompiling the first program in the previous section with ILSpy, we can observe that a compiler-generated proxy class named <>E__0<T> is created. This class contains the extension members as if they were declared directly on the target type — exactly how we would like them to appear.

We can also see that extension properties are compiled as methods with name prefixed with get_. For anyone familiar with decompiling .NET code, this comes as no surprise — since the very beginning of C#, property getters have always been compiled this way. Also, property setters name are prefixed with set_.

csharp-extension-everything-decompiled

 

Disambiguating extension members

Let’s address disambiguation. Until now, when multiple extension methods shared a similar signature, or hide an actual instance method, you had to disambiguate by explicitly prefixing the call with the name of the static class that defines the extension. This approach remains the standard way to resolve ambiguity and still applies to C# 14 extension members.

To the best of my knowledge, this is the first time the get_ or set_ property accessor prefixes appear explicitly in user-written C# code.

Some extension methods cannot be ported to the new C# 14 syntax

It’s worth noting that some complex extension methods cannot be ported to the new C# 14 syntax. The C# compiler requires all generic type parameters to be consumed in the receiver declaration. This is best illustrated in the following screenshot:

csharp-extension-invalid-syntax

Also when a generic type parameter has some constraints, the extension method cannot be ported:

C# 14 and .NET 10 Preview

This article is based on C# 14 and .NET 10 Preview 6. If you’d like to try out extension everything before the official release in November 2025, you’ll need to use Visual Studio 2025 Preview, install the .NET 10 SDK, and update your .csproj file as follows:

This article will be updated upon RTM release.

Conclusion

Microsoft’s language designers have been thinking long and hard about how to extend extensions — literally. Managing all aspects—avoiding receiver repetition, handling disambiguation and generics, and ensuring no breaking changes—has been a challenging task.

With C# 14, we finally get a clean, unified and consistent syntax that brings some powerful benefits:

  • You can group related extension members by receiver type.

  • Extension properties are now supported.

  • You can even define static extension members.

  • Even more importantly, extension users never have to worry about how extensions are written. Whether using the old this-parameter syntax or the new style, extensions should behave identically, ensuring existing methods keep working and users experience no disruption when authors update the syntax.

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *