loading experience

C#

C# 14: extension members explained with examples

After extension methods come extension properties and static extension members, grouped in extension blocks.

C# 14: extension members explained with examples

Extension methods have existed since C# 3, but they only let you add methods. C# 14 introduces extension blocks, which also let you define extension properties and static extension members on an existing type.

An extension block groups every member that extends the same type.
An extension block groups every member that extends the same type.

The new syntax

Inside a static class you declare an extension block with the "receiver", that is the type being extended. Every member of the block can use that receiver.

public static class StringExtensions
{
    extension(string text)
    {
        // extension property
        public bool IsBlank => string.IsNullOrWhiteSpace(text);

        // extension method, as before but without "this"
        public string Truncate(int max) =>
            text.Length <= max ? text : text[..max] + "...";
    }
}

var title = "Introduction to .NET 10";
Console.WriteLine(title.IsBlank);       // False
Console.WriteLine(title.Truncate(12));  // Introduction...

Static extension members

By omitting the parameter name you extend the type itself, not an instance: you can add "static" methods or properties to a type you do not control.

public static class GuidExtensions
{
    extension(Guid)
    {
        public static Guid FromText(string value) =>
            Guid.TryParse(value, out var g) ? g : Guid.Empty;
    }
}

var id = Guid.FromText("not-valid"); // Guid.Empty

Compatibility

Old extension methods with this keep working and can live alongside the new blocks. There is nothing to rewrite: adopt extension blocks when you need properties or static members, or when you want to group several extensions of the same type.

Tips

  • Use extension properties for derived information without side effects.
  • Avoid "stuffing" system types with dozens of extensions: prefer dedicated namespaces.
  • Remember that an instance member always takes precedence over an extension with the same name.
Comments (0)

No comments yet.

Leave a comment