---
title: "Extensions get an update in .NET 10"
description: "With the latest preview: .NET 10 preview 3, we did get an overhaul on **extensions**. It might enable some nice tricks in the future."
updated: 2025-04-21
tags: [".NET 10", ".NET", "C#", "C# 14"]
canonical: "https://steven-giesel.com/blogPost/d84875c9-c363-45ac-b716-d0b4047396cf/extensions-get-an-update-in-net-10"
---

# Extensions get an update in .NET 10

With the latest preview: .NET 10 preview 3, we did get an overhaul on **extensions**. It might enable some nice tricks in the future.

## Extensions

The new feature called [**Extension members**](https://github.com/dotnet/core/blob/main/release-notes/10.0/preview/preview3/csharp.md#extension-members) is basically extending the already existing extensions and bringing them to the next level.

If we had this in the pre-C# 14 world:
```csharp
public static class Extensions
{
    public static IEnumerable<int> WhereGreaterThan(this IEnumerable<int> source, int threshold) 
        => source.Where(x => x > threshold);
}
```

We can achieve the same with this new syntax:
```csharp
public static class Extensions
{
    extension(IEnumerable<int> source) 
    {
        public IEnumerable<int> WhereGreaterThan(int threshold)
            => source.Where(x => x > threshold);

        public bool IsEmpty
            => !source.Any();
    }
}
```

As you can see, we can group similiar things easier together. Until now, this is basically a new syntax but we didn't achieve anything new. But that changes:

## Extending with static methods

The new cool thing is that you can new static methods on top of a type:
```csharp
extension<T>(List<T>)
{
    public static List<T> Create()
        => [];
}
```

Now, you can call:
```csharp
var foo = List<int>.Create();
```

Okay, so far, so good. But what can we do with that? Well there are two cool features that might be possible (they are not right now).

## Adding static operators to 3rd party types

We can easily add `operator`s to existing 3rd party types. They are defined as static invocations on a type, so we can do something like this:
```csharp
public class MyObject(int number)
{
    public int Number { get; } = number;
}

public static class Extensions
{
    extension(MyObject)
    {
        public static int operator +(MyObject x, MyObject y)
        {
            return x.Number + y.Number;
        }
    }
}
```

Remember `MyObject` itself doesn't define any `+` but the extension does. So we would be allowed to do something like:
```csharp
var m1 = new MyObject(2);
var m2 = new MyObject(3);
Console.WriteLine(m1 + m2);
```

## Adding new collection expressions on unsupported types

Basically, what we want is to allow the `[1,2,3]` syntax for types that currently don't support that. I took as an example `IReadOnlySet<T>`. If you are not aware what collection expressions are or how to build them for your own types: https://andrewlock.net/behind-the-scenes-of-collection-expressions-part-5-adding-support-for-collection-expressions-to-your-own-types/

So, while currently not working, we might have a chance that we can equip 3rd party types as such:
```csharp
IReadOnlySet<int> set = [1, 2, 3];

[CollectionBuilder(typeof(Extensions), nameof(Extensions.Create))]
public static class Extensions
{
    extension<T>(IReadOnlySet<T>)
    {
        public IReadOnlySet<T> Create(ReadOnlySpan<T> items)
        {
            return new HashSet<T>(); // Here something useful
        }
    }
}
```

The problem is that the compiler doesn't look on any other type than the target type for the attribute - so while the extension does compile, it does not create the effect I was aiming for. Let's see in the future which cool things we can enable with this new language feature.