Skip to content

Commit 499ba59

Browse files
committed
Add Extension operators
Fixes #47268 Fixes #47280 Extension indexers didn't make C# 14 (although properties did). Remove those examples. Add examples and discussion for extension operators, which are available in RC1.
1 parent b574b4b commit 499ba59

File tree

4 files changed

+19
-11
lines changed

4 files changed

+19
-11
lines changed

docs/csharp/language-reference/keywords/extension.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
---
22
title: "Extension member declarations"
33
description: "Learn the syntax to declare extension members in C#. Extension members enable you to add functionality to types and interfaces in those instances where you don't have the source for the original type. Extensions are often paired with generic interfaces to implement a common set of functionality across all types that implement that interface."
4-
ms.date: 04/17/2025
4+
ms.date: 09/17/2025
55
f1_keywords:
66
- "extension_CSharpKeyword"
77
- "extension"
88
---
99
# Extension declaration (C# Reference)
1010

11-
Beginning with C# 14, top level, nongeneric `static class` declarations can use `extension` containers to declare *extension members*. Extension members are methods or properties and can appear to be instance or static members. Earlier versions of C# enable *extension methods* by adding `this` as a modifier to the first parameter of a static method declared in a top-level, nongeneric static class.
11+
Beginning with C# 14, top level, nongeneric `static class` declarations can use `extension` blocks to declare *extension members*. Extension members are methods or properties and can appear to be instance or static members. Earlier versions of C# enable *extension methods* by adding `this` as a modifier to the first parameter of a static method declared in a top-level, nongeneric static class.
1212

13-
The `extension` block specifies the type and receiver for extension members. You can declare methods and properties inside the `extension` declaration. The following example declares a single extension block that defines an instance extension method and an instance property.
13+
The `extension` block specifies the type and receiver for extension members. You can declare methods, properties or operators inside the `extension` declaration. The following example declares a single extension block that defines an instance extension method, an instance property, and a static operator method.
1414

1515
:::code language="csharp" source="./snippets/extensions.cs" id="ExtensionMembers":::
1616

@@ -20,14 +20,16 @@ Any of the extension members can be accessed as though they were members of the
2020

2121
:::code language="csharp" source="./snippets/extensions.cs" id="UseExtensionMethod":::
2222

23-
You can declare any number of members in a single container, as long as they share the same receiver. You can declare as many extension blocks in a single class as well. Different extensions don't need to declare the same type or name of receiver. The extension parameter doesn't need to include the parameter name if the only members are static:
23+
You can declare any number of members in a single block, as long as they share the same receiver. You can declare as many extension blocks in a single class as well. Different extensions don't need to declare the same type or name of receiver. The extension parameter doesn't need to include the parameter name if the only members are static:
2424

2525
:::code language="csharp" source="./snippets/extensions.cs" id="StaticExtensions":::
2626

2727
Static extensions can be called as though they're static members of the receiver type:
2828

2929
:::code language="csharp" source="./snippets/extensions.cs" id="UseStaticExtensions":::
3030

31+
Operators are called as though they are user defined operators on the type.
32+
3133
> [!IMPORTANT]
3234
> An extension doesn't introduce a *scope* for member declarations. All members declared in a single class, even if in multiple extensions, must have unique signatures. The generated signature includes the receiver type in its name for static members and the receiver parameter for extension instance members.
3335

docs/csharp/language-reference/keywords/snippets/Extensions.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ public int Median
3535
}
3636
}
3737

38-
public int this[int index] => sequence.Skip(index).First();
38+
public static IEnumerable<int> operator +(IEnumerable<int> left, IEnumerable<int> right)
39+
=> left.Concat(right);
3940
}
4041
}
4142
// </ExtensionMembers>
@@ -102,6 +103,8 @@ public static void BasicExample()
102103
numbers = numbers.AddValue(10);
103104

104105
var median = numbers.Median;
106+
107+
var combined = numbers + Enumerable.Range(100, 10);
105108
// </UseExtensionMethod>
106109

107110
// <UseStaticExtensions>

docs/csharp/programming-guide/classes-and-structs/extension-methods.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "Extension members"
33
description: Extension members in C# enable you to add methods, properties, or operators to existing types without creating a new derived type, recompiling, or otherwise modifying the original type.
4-
ms.date: 04/15/2025
4+
ms.date: 09/17/2025
55
helpviewer_keywords:
66
- "methods [C#], adding to existing types"
77
- "extension methods [C#]"
@@ -12,7 +12,9 @@ helpviewer_keywords:
1212

1313
Extension members enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type.
1414

15-
Beginning with C# 14, there are two syntaxes you use to define extension methods. C# 14 adds [`extension`](../../language-reference/keywords/extension.md) containers, where you define multiple extension members for a type or an instance of a type. Before C# 14, you add the [`this`](../../language-reference/keywords/this.md) modifier to the first parameter of a static method to indicate that the method appears as a member of an instance of the parameter type.
15+
Beginning with C# 14, there are two syntaxes you use to define extension methods. C# 14 adds [`extension`](../../language-reference/keywords/extension.md) blocks, where you define multiple extension members for a type or an instance of a type. Before C# 14, you add the [`this`](../../language-reference/keywords/this.md) modifier to the first parameter of a static method to indicate that the method appears as a member of an instance of the parameter type.
16+
17+
Extension blocks support multiple member types: methods, properties, and operators. With extension blocks, you can define both instance extensions and static extensions. Instance extensions extend an instance of the type; static extensions extend the type itself. The form of extension methods declared with the `this` modifier supports instance extension methods.
1618

1719
Extension methods are static methods, but they're called as if they were instance methods on the extended type. For client code written in C#, F# and Visual Basic, there's no apparent difference between calling an extension method and the methods defined in a type. Both forms of extension methods are compiled to the same IL (Intermediate Language). Consumers of extension members don't need to know which syntax was used to define extension methods.
1820

docs/csharp/whats-new/csharp-14.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: What's new in C# 14
33
description: Get an overview of the new features in C# 14. C# 14 ships with .NET 10.
4-
ms.date: 04/17/2025
4+
ms.date: 09/17/2025
55
ms.topic: whats-new
66
ms.update-cycle: 180-days
77
---
@@ -30,7 +30,7 @@ You can find any breaking changes introduced in C# 14 in our article on [breakin
3030

3131
## Extension members
3232

33-
C# 14 adds new syntax to define *extension members*. The new syntax enables you to declare *extension properties* in addition to extension methods. You can also declare extension members that extend the type, rather than an instance of the type. In other words, these new extension members can appear as static members of the type you extend. The following code example shows an example of the different kinds of extension members you can declare:
33+
C# 14 adds new syntax to define *extension members*. The new syntax enables you to declare *extension properties* in addition to extension methods. You can also declare extension members that extend the type, rather than an instance of the type. In other words, these new extension members can appear as static members of the type you extend. These extensions can include user defined operators implemented as static extension methods. The following code example shows an example of the different kinds of extension members you can declare:
3434

3535
```csharp
3636
public static class Enumerable
@@ -40,8 +40,6 @@ public static class Enumerable
4040
{
4141
// Extension property:
4242
public bool IsEmpty => !source.Any();
43-
// Extension indexer:
44-
public TSource this[int index] => source.Skip(index).First();
4543

4644
// Extension method:
4745
public IEnumerable<TSource> Where(Func<TSource, bool> predicate) { ... }
@@ -55,6 +53,9 @@ public static class Enumerable
5553

5654
// static extension property:
5755
public static IEnumerable<TSource> Identity => Enumerable.Empty<TSource>();
56+
57+
// static user defined operator:
58+
public static IEnumerable<TSource> operator + (IEnumerable<TSource> left, IEnumerable<TSource> right) => left.Concat(right);
5859
}
5960
}
6061
```

0 commit comments

Comments
 (0)