You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add examples for XML on extension members (#50551)
* Add examples for XML on `extension`s
Fixes#49956
Add examples and explanations for writing documentation on `extension` nodes.
Include how the XML comments on the `extension` node for `<summary>`, `<param>` and `<typeparam>` are copied to all members of that extension block.
* forgot the XML tag
* Copilot style feedback.
* Apply suggestions from code review
Co-authored-by: Genevieve Warren <[email protected]>
* Respond to feedback.
---------
Co-authored-by: Genevieve Warren <[email protected]>
Copy file name to clipboardExpand all lines: docs/csharp/language-reference/keywords/extension.md
+12-9Lines changed: 12 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,34 +1,37 @@
1
1
---
2
2
title: "Extension member declarations"
3
3
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: 09/17/2025
4
+
ms.date: 12/11/2025
5
5
f1_keywords:
6
6
- "extension_CSharpKeyword"
7
7
- "extension"
8
8
---
9
9
# Extension declaration (C# Reference)
10
10
11
-
Beginning with C# 14, toplevel, 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.
11
+
Starting 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.
12
12
13
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.
14
14
15
+
> [!NOTE]
16
+
> All the examples in this article include XML comments for the members and the extension block. The node on the `extension` block describes the extended type and the receiver parameter. The C# compiler copies this node to the generated member for all members in the extension block. These examples demonstrate the preferred style for generating XML documentation for extension members.
The `extension` defines the receiver: `sequence`, which is an `IEnumerable<int>`. The receiver type can be nongeneric, an open generic, or a closed generic type. The name `sequence` is in scope in every instance member declared in that extension. The extension method and property both access `sequence`.
18
21
19
-
Any of the extension members can be accessed as though they were members of the receiver type:
22
+
You access any of the extension members as though they were members of the receiver type:
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:
Operators are called as though they're user defined operators on the type.
34
+
You call operators as though they're user defined operators on the type.
32
35
33
36
> [!IMPORTANT]
34
37
> 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.
@@ -37,18 +40,18 @@ The following example shows an extension method using the `this` modifier:
Both forms of extension methods generate the same intermediate language (IL). Callers can't make a distinction between them. In fact, you can convert existing extension methods to the new member syntax without a breaking change. The formats are both binary and source compatible.
45
48
46
49
## Generic extension blocks
47
50
48
-
Where you specify the type parameters for an extension member declared in an extension block depends on where that type parameter is required:
51
+
Where you specify the type parameters for an extension member declared in an extension block depends on where you need the type parameter:
49
52
50
-
-You add the type parameter to the `extension` declaration when the type parameter is used in the receiver.
51
-
-You add the type parameter to the member declaration when the type is distinct from any type parameter specified on the receiver.
53
+
-Add the type parameter to the `extension` declaration when the type parameter is used in the receiver.
54
+
-Add the type parameter to the member declaration when the type is distinct from any type parameter specified on the receiver.
52
55
- You can't specify the same type parameter in both locations.
53
56
54
57
The following example shows an extension block for `IEnumerable<T>` where two of the extension members require a second type parameter:
description: See documentation examples on many different C# language elements. Learn which tags to use in different situations and for different language elements.
4
-
ms.date: 07/14/2021
4
+
ms.date: 12/11/2025
5
5
ms.topic: how-to
6
6
---
7
7
# Example XML documentation comments
8
8
9
-
This article contains three examples for adding XML documentation comments to most C# language elements. The first example shows how you document a class with different members. The second shows how you would reuse explanations for a hierarchy of classes or interfaces. The third shows tags to use for generic classes and members. The second and third examples use concepts that are covered in the first example.
9
+
This article contains three examples for adding XML documentation comments to most C# language elements. The first example shows how you document a class with different members. The second example shows how you can reuse explanations for a hierarchy of classes or interfaces. The third example shows tags to use for generic classes and members. The second and third examples use concepts that are covered in the first example.
10
10
11
11
## Document a class, struct, or interface
12
12
13
13
The following example shows common language elements, and the tags you'll likely use to describe these elements. The documentation comments describe the use of the tags, rather than the class itself.
Adding documentation can clutter your source code with large sets of comments intended for users of your library. You use the `<Include>` tag to separate your XML comments from your source. Your source code references an XML file with the `<Include>` tag:
17
+
Adding documentation can clutter your source code with large sets of comments intended for users of your library. Use the `<Include>` tag to separate your XML comments from your source. Your source code references an XML file by using the `<Include>` tag:
The `<inheritdoc>` element means a type or member *inherits* documentation comments from a base class or interface. You can also use the `<inheritdoc>` element with the `cref` attribute to inherit comments from a member of the same type. The following example shows ways to use this tag. Note that when you add the `inheritdoc` attribute to a type, member comments are inherited. You can prevent the use of inherited comments by writing comments on the members in the derived type. Those will be chosen over the inherited comments.
27
+
The `<inheritdoc>` element means a type or member *inherits* documentation comments from a base class or interface. You can also use the `<inheritdoc>` element with the `cref` attribute to inherit comments from a member of the same type. The following example shows ways to use this tag. When you add the `inheritdoc` attribute to a type, member comments are inherited. You can prevent the use of inherited comments by writing comments on the members in the derived type. Those comments are chosen over the inherited comments.
You may find that the code is obscured by all the comments. The final example shows how you would adapt this library to use the `include` tag. You move all the documentation to an XML file:
51
+
You might find that the code is obscured by all the comments. The final example shows how you adapt this library to use the `include` tag. You move all the documentation to an XML file:
@@ -52,4 +60,4 @@ The code uses the `<include>` tag to reference the appropriate element in the XM
52
60
- The `file` attribute represents the name of the XML file containing the documentation.
53
61
- The `path` attribute represents an [XPath](../../../standard/data/xml/xpath-queries-and-namespaces.md) query to the `tag name` present in the specified `file`.
54
62
- The `name` attribute represents the name specifier in the tag that precedes the comments.
55
-
- The `id` attribute, which can be used in place of `name`, represents the ID for the tag that precedes the comments.
63
+
- The `id` attribute, which you can use in place of `name`, represents the ID for the tag that precedes the comments.
0 commit comments