From 7c41a3827235a59f9f1d7112d21365045164a727 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Fri, 18 Apr 2025 16:18:53 -0400 Subject: [PATCH 1/2] Add an overview of extension members Add an overview of the extension member feature in the What's new in C# 14 article. --- docs/csharp/whats-new/csharp-14.md | 33 +++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/docs/csharp/whats-new/csharp-14.md b/docs/csharp/whats-new/csharp-14.md index 17c8ad027efc2..c7a6a2c1a587f 100644 --- a/docs/csharp/whats-new/csharp-14.md +++ b/docs/csharp/whats-new/csharp-14.md @@ -28,7 +28,38 @@ You can find any breaking changes introduced in C# 14 in our article on [breakin ## Extension members -You can learn more details by reading the [feature specification](~/_csharplang/proposals/extensions.md) for the new extension members feature. +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: + +```csharp +public static class Enumerable +{ + // Extension block + extension(IEnumerable source) // extension members for IEnumerable + { + // Extension property: + public bool IsEmpty => source.Any() == false; + // Extension indexer: + public int this[int index] => source.Skip(index).First(); + + // Extension method: + public IEnumerable Where(Func predicate) { ... } + } + + // extension block, with a receiver type only + extension(IEnumerable) // static extension members for IEnumerable + { + // static extension method: + public static IEnumerable Combine(IEnumerable first, IEnumerable second) { ... } + + // static extension property: + public static IEnumerable Identity => yield return default; + } +} +``` + +The members in the first extension block are called as though they are instance members of `IEnumerable`, for example `sequence.IsEmpty`. The members in the second extension block are called as though they are static members of `IEnumerable`, for example `IEnumerable.Identity`. + +You can learn more details by reading the article on [extension members](../programming-guide/classes-and-structs/extension-methods.md) in the programming guide, the language reference article on the [`extension` keyword](../language-reference/keywords/extension.md), and the [feature specification](~/_csharplang/proposals/extensions.md) for the new extension members feature. ## The `field` keyword From fe02e589f5d91465d7e2c3b29071bd6dff084e72 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Fri, 18 Apr 2025 16:21:26 -0400 Subject: [PATCH 2/2] proofread --- docs/csharp/whats-new/csharp-14.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/csharp/whats-new/csharp-14.md b/docs/csharp/whats-new/csharp-14.md index c7a6a2c1a587f..8a83f1ecd189f 100644 --- a/docs/csharp/whats-new/csharp-14.md +++ b/docs/csharp/whats-new/csharp-14.md @@ -57,7 +57,7 @@ public static class Enumerable } ``` -The members in the first extension block are called as though they are instance members of `IEnumerable`, for example `sequence.IsEmpty`. The members in the second extension block are called as though they are static members of `IEnumerable`, for example `IEnumerable.Identity`. +The members in the first extension block are called as though they're instance members of `IEnumerable`, for example `sequence.IsEmpty`. The members in the second extension block are called as though they're static members of `IEnumerable`, for example `IEnumerable.Identity`. You can learn more details by reading the article on [extension members](../programming-guide/classes-and-structs/extension-methods.md) in the programming guide, the language reference article on the [`extension` keyword](../language-reference/keywords/extension.md), and the [feature specification](~/_csharplang/proposals/extensions.md) for the new extension members feature. @@ -155,7 +155,7 @@ You can simplify the preceding code using the `?.` operator: customer?.Order = GetCurrentOrder(); ``` -The right side of the `=` operator is evaluated only when the left side is not null. If `customer` is null, the code doesn't call `GetCurrentOrder`. +The right side of the `=` operator is evaluated only when the left side isn't null. If `customer` is null, the code doesn't call `GetCurrentOrder`. In addition to assignment, you can use null conditional member access operators with compound assignment operators (`+=`, `-=`, and others). However, increment and decrement, `++` and `--`, aren't allowed.