Skip to content

Commit 6303b18

Browse files
BillWagnergewarren
andauthored
Clean edit pass on attributes (#44513)
* Add page for custom attributes Fixes #42850: Add a new page to reference attributes that cause the compiler to emit different IL modifiers instead of putting the attribute in the emitted IL. * Add additional attributes Fixes #43109 Most of these have been added to the general page. A few are expressed in source differently, and were added to the new pseudo-attributes page. * Fixes #43110 Add a list of attributes that are written by the compiler that shouldn't be added in users' source code. * Add any atributes to displayName Some attributes weren't in the `displayName` element for the TOC. Review all of them and add them again. * edit pass * Fix build warnings Mostly fix anchors. The one C# 9 spec was never intended to be published. * Apply suggestions from code review Co-authored-by: Genevieve Warren <[email protected]> * Respond to feedback. * rebase and merbe * link between attributes Link between the C# attribute page and the .NET fundamentals article on experimental attributes in the runtime. --------- Co-authored-by: Genevieve Warren <[email protected]>
1 parent 679b721 commit 6303b18

File tree

10 files changed

+118
-16
lines changed

10 files changed

+118
-16
lines changed

docs/csharp/language-reference/attributes/general.md

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,29 @@
11
---
22
title: "Attributes interpreted by the compiler: Miscellaneous"
3-
ms.date: 11/22/2024
3+
ms.date: 01/24/2025
44
description: "Learn about attributes that affect code generated by the compiler: the Conditional, Obsolete, AttributeUsage, ModuleInitializer, and SkipLocalsInit attributes."
55
---
66
# Miscellaneous attributes interpreted by the C# compiler
77

88
There are several attributes that can be applied to elements in your code that add semantic meaning to those elements:
99

1010
- [`Conditional`](#conditional-attribute): Make execution of a method dependent on a preprocessor identifier.
11-
- [`Obsolete`](#obsolete-attribute): Mark a type or member for (potential) future removal.
11+
- [`Obsolete`](#obsolete-and-deprecated-attribute): Mark a type or member for (potential) future removal.
12+
- [`Deprecated`](#obsolete-and-deprecated-attribute): (Windows Foundation) Mark a type or member for (potential) future removal.
13+
- [`Experimental`](#experimental-attributes): Mark a type or member as experimental.
14+
- [`SetsRequiredMembers`](#setsrequiredmembers-attribute): Indicate that a constructor sets all required properties.
1215
- [`AttributeUsage`](#attributeusage-attribute): Declare the language elements where an attribute can be applied.
1316
- [`AsyncMethodBuilder`](#asyncmethodbuilder-attribute): Declare an async method builder type.
1417
- [`InterpolatedStringHandler`](#interpolatedstringhandler-and-interpolatedstringhandlerarguments-attributes): Define an interpolated string builder for a known scenario.
1518
- [`ModuleInitializer`](#moduleinitializer-attribute): Declare a method that initializes a module.
1619
- [`SkipLocalsInit`](#skiplocalsinit-attribute): Elide the code that initializes local variable storage to 0.
1720
- [`UnscopedRef`](#unscopedref-attribute): Declare that a `ref` variable normally interpreted as `scoped` should be treated as unscoped.
1821
- [`OverloadResolutionPriority`](#overloadresolutionpriority-attribute): Add a tiebreaker attribute to influence overload resolution for possibly ambiguous overloads.
19-
- [`Experimental`](#experimental-attribute): Mark a type or member as experimental.
22+
- [`EnumeratorCancellation`](#enumeratorcancellation-attribute): Specify the parameter for a cancellation token in an async enumerator.
23+
- [`CollectionBuilder`](#collectionbuilder-attribute): Specify the builder method for a collection type when a collection expression is converted to that collection type.
24+
- [`InlineArray`](#inlinearray-attribute): Specify that a `struct` type is an *inline array*.
25+
- [`IUnknownConstant`](#iunknownconstant-and-idispatchconstant-attributes): Specifies how a missing argument should be supplied for a default parameter.
26+
- [`IDispatchConstant`](#iunknownconstant-and-idispatchconstant-attributes): Specifies how a missing argument should be supplied for a default parameter.
2027

2128
The compiler uses those semantic meanings to alter its output and report possible mistakes by developers using your code.
2229

@@ -46,7 +53,7 @@ The `Conditional` attribute can also be applied to an attribute class definition
4653

4754
:::code language="csharp" source="snippets/ConditionalExamples.cs" ID="SnippetConditionalConditionalAttribute" :::
4855

49-
## `Obsolete` attribute
56+
## `Obsolete` and `Deprecated` attribute
5057

5158
The `Obsolete` attribute marks a code element as no longer recommended for use. Use of an entity marked obsolete generates a warning or an error. The `Obsolete` attribute is a single-use attribute and can be applied to any entity that allows attributes. `Obsolete` is an alias for <xref:System.ObsoleteAttribute>.
5259

@@ -58,15 +65,19 @@ The string provided as the first argument to the attribute constructor is displa
5865

5966
:::code language="csharp" source="snippets/ObsoleteExample.cs" id="Snippet2" :::
6067

61-
## `Experimental` attribute
68+
The Windows Foundation Metadata libraries use the <xref:Windows.Foundation.Metadata.DeprecatedAttribute?displayProperty=nameWithType> instead of the `ObsoleteAttribute`.
69+
70+
## `Experimental` attributes
6271

6372
Beginning in C# 12, types, methods, and assemblies can be marked with the <xref:System.Diagnostics.CodeAnalysis.ExperimentalAttribute?displayProperty=nameWithType> to indicate an experimental feature. The compiler issues a warning if you access a method or type annotated with the <xref:System.Diagnostics.CodeAnalysis.ExperimentalAttribute>. All types declared in an assembly or module marked with the `Experimental` attribute are experimental. The compiler issues a warning if you access any of them. You can disable these warnings to pilot an experimental feature.
6473

6574
> [!WARNING]
66-
> Experimental features are subject to changes. The APIs may change, or they may be removed in future updates. Including experimental features is a way for library authors to get feedback on ideas and concepts for future development. Use extreme caution when using any feature marked as experimental.
75+
> Experimental features are subject to changes. The APIs can change, or they can be removed in future updates. Including experimental features is a way for library authors to get feedback on ideas and concepts for future development. Use extreme caution when using any feature marked as experimental. You can learn more about how APIs are marked as experimental in our article on [preview APIs](../../../fundamentals/runtime-libraries/preview-apis.md#experimentalattribute).
6776
6877
You can read more details about the `Experimental` attribute in the [feature specification](~/_csharplang/proposals/csharp-12.0/experimental-attribute.md).
6978

79+
The Windows Foundation Metadata libraries use the <xref:Windows.Foundation.Metadata.ExperimentalAttribute?displayProperty=nameWithType>, which predates C# 12.
80+
7081
## `SetsRequiredMembers` attribute
7182

7283
The `SetsRequiredMembers` attribute informs the compiler that a constructor sets all `required` members in that class or struct. The compiler assumes any constructor with the <xref:System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute?displayProperty=fullName> attribute initializes all `required` members. Any code that invokes such a constructor doesn't need object initializers to set required members. Adding the `SetsRequiredMembers` attribute is primarily useful for positional records and primary constructors.
@@ -242,6 +253,22 @@ Overload resolution considers the two methods equally good for some argument typ
242253

243254
All overloads with a lower priority than the highest overload priority are removed from the set of applicable methods. Methods without this attribute have the overload priority set to the default of zero. Library authors should use this attribute as a last resort when adding a new and better method overload. Library authors should have a deep understanding of how [Overload resolution](~/_csharplang/proposals/csharp-13.0/overload-resolution-priority.md#overload-resolution-priority) impacts choosing the better method. Otherwise, unexpected errors can result.
244255

256+
## EnumeratorCancellation attribute
257+
258+
The <xref:System.Runtime.CompilerServices.EnumeratorCancellationAttribute?displayProperty=nameWithType> attribute specifies which parameter should receive the cancellation token from the <xref:System.Collections.Generic.IAsyncEnumerable`1.GetAsyncEnumerator(System.Threading.CancellationToken)?displayProperty=fullName> API. It's part of the infrastructure for the [async streams](../../asynchronous-programming/generate-consume-asynchronous-stream.md) feature.
259+
260+
## CollectionBuilder attribute
261+
262+
The <xref:System.Runtime.CompilerServices.CollectionBuilderAttribute?displayProperty=nameWithType> attribute specifies a method that builds an instance of a collection type from a [collection expression](../operators/collection-expressions.md). You use this attribute to specify a method that builds the collection. The compiler generates code to call that method when a collection expression is converted to that type.
263+
264+
## InlineArray attribute
265+
266+
The <xref:System.Runtime.CompilerServices.InlineArrayAttribute?displayProperty=nameWithType> attribute marks a type as an [inline array](../builtin-types/struct.md#inline-arrays). You can learn more about this feature in the article on `structs`, in the section on [inline arrays](../builtin-types/struct.md#inline-arrays).
267+
268+
## IUnknownConstant and IDispatchConstant attributes
269+
270+
The <xref:System.Runtime.CompilerServices.IUnknownConstantAttribute?displayProperty=nameWithType> and <xref:System.Runtime.CompilerServices.IDispatchConstantAttribute?displayProperty=nameWithType> attributes can be added to default parameters to indicate that a missing argument should be supplied as `new UnknownWrapper(null)` or `new DispatchWrapper(null)`.
271+
245272
## See also
246273

247274
- <xref:System.Attribute>
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
---
2+
title: "Attributes interpreted by the compiler: Pseudo-attributes"
3+
ms.date: 01/2/2025
4+
description: "Learn about attributes you can add to code that are written to IL as modifiers. These custom attributes aren't emitted as attributes in the compiled output."
5+
---
6+
# Custom attributes that generate flags or options in the Intermediate Language (IL) output
7+
8+
You add these attributes to your code for the compiler to emit a specified Intermediate Language (IL) modifier. These attributes instruct the compiler to include the corresponding IL modifier in the output.
9+
10+
| Attribute | Modifier | Comments |
11+
|--------------------------------------------------------------------------------------|-----------------|-----------|
12+
| <xref:System.Runtime.InteropServices.ComImportAttribute?displayProperty=fullName> | `import` | |
13+
| <xref:System.Runtime.InteropServices.DllImportAttribute?displayProperty=fullName> | `pinvokeimpl` | You can add options listed in the constructor. |
14+
| <xref:System.Runtime.InteropServices.FieldOffsetAttribute?displayProperty=fullName> | `.field` | This sets the field offset for memory layout. |
15+
| <xref:System.Runtime.InteropServices.MarshalAsAttribute> | `marshal` | You can set options listed in the constructor. |
16+
| <xref:System.Runtime.CompilerServices.MethodImplAttribute?displayProperty=fullName> | `flag` | Constructor arguments specify specific named flags such as `aggressiveinlining` or `forwardref`. These flags also specify the `native`, `managed`, or `optil` modifiers for the <xref:System.Runtime.CompilerServices.MethodCodeType?displayProperty=fullName> field. |
17+
| <xref:System.NonSerializedAttribute?displayProperty=fullName> | `notserialized` | |
18+
| <xref:System.Runtime.InteropServices.OptionalAttribute?displayProperty=fullName> | `[opt]` | |
19+
| <xref:System.Runtime.InteropServices.OutAttribute?displayProperty=fullName> | `[out]` | |
20+
| <xref:System.Runtime.InteropServices.PreserveSigAttribute?displayProperty=fullName> | `preservesig` | |
21+
| <xref:System.SerializableAttribute?displayProperty=fullName> | `serializable` | |
22+
| <xref:System.Runtime.InteropServices.StructLayoutAttribute?displayProperty=fullName> | `auto`, `sequential`, or `explicit` | Layout options can be set using the parameters. |
23+
| <xref:System.Runtime.CompilerServices.IndexerNameAttribute?displayProperty=fullName> | | You add this attribute to an indexer to set a different method name. By default, indexers are compiled to a property named `Item`. You can specify a different name using this attribute. |
24+
25+
Some of these custom attributes are applied using other C# syntax rather than adding the attribute to your source code.
26+
27+
| Attribute | Comments |
28+
|--------------------------------------------------------------------------------------------------|----------|
29+
| <xref:System.Runtime.InteropServices.DefaultParameterValueAttribute?displayProperty=fullName> | Specifies the default value for the parameter. Use the [default parameter syntax](../../methods.md#optional-parameters-and-arguments). |
30+
| <xref:System.Runtime.InteropServices.InAttribute?displayProperty=fullName> | Specifies the IL `[in]` modifier. Use the [`in`](../keywords/method-parameters.md#in-parameter-modifier) or [`ref readonly`](../keywords/method-parameters.md#ref-readonly-modifier). |
31+
| <xref:System.Runtime.CompilerServices.SpecialNameAttribute?displayProperty=fullName> | Specifies the IL `specialname` modifier. The compiler automatically adds this modifier for methods that require it. |
32+
| <xref:System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute?displayProperty=nameWithType> | This attribute is required for the `delegate*` feature. The compiler adds it to any [`delegate*`](../unsafe-code.md#function-pointers) that requires its use. |
33+
34+
The following custom attributes are generally disallowed in C# source. They're listed here to aid library authors who use reflection, and to ensure you don't create custom attributes with the same name.
35+
36+
| Attribute | Comments |
37+
|--------------------------------------------------------------------------------------------------|---------|
38+
| <xref:System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute?displayProperty=fullName> | Prevents downlevel compilers from using metadata it can't safely understand. |
39+
| <xref:System.Runtime.CompilerServices.DecimalConstantAttribute?displayProperty=fullName> | Encodes `const decimal` fields. The runtime doesn't support `decimal` values as constant values. |
40+
| <xref:System.Reflection.DefaultMemberAttribute?displayProperty=fullName> | Encodes indexers with <xref:System.Runtime.CompilerServices.IndexerNameAttribute?displayProperty=fullName>. This attribute notes the default indexer when its name is different than `Item`. This attribute is allowed in source. |
41+
| <xref:System.Runtime.CompilerServices.DynamicAttribute?displayProperty=fullName> | Encodes whether a type in a signature is `dynamic` (versus `object`). |
42+
| <xref:System.Runtime.CompilerServices.ExtensionAttribute?displayProperty=fullName> | This attribute notes extension methods. The compiler also places this attribute on the containing classes. |
43+
| <xref:System.Runtime.CompilerServices.FixedBufferAttribute?displayProperty=fullName> | This attribute specifies `fixed` struct fields. |
44+
| <xref:System.Runtime.CompilerServices.IsByRefLikeAttribute?displayProperty=fullName> | This attribute specifies a `ref` struct. |
45+
| <xref:System.Runtime.CompilerServices.IsReadOnlyAttribute?displayProperty=fullName> | This attribute indicates that a parameter has the `in` modifier. It distinguishes `in` parameters from `readonly ref` or `[In] ref`. |
46+
| <xref:System.Runtime.CompilerServices.RequiresLocationAttribute?displayProperty=fullName> | This attribute indicates that a parameter has the `readonly ref` modifier. It distinguishes `readonly ref` from `in` or `[In] ref`. |
47+
| <xref:System.Runtime.CompilerServices.IsUnmanagedAttribute?displayProperty=fullName> | This attribute specifies the `unmanaged` constraint on a type parameter. |
48+
| <xref:System.Runtime.CompilerServices.NullableAttribute?displayProperty=fullName>, <xref:System.Runtime.CompilerServices.NullableContextAttribute?displayProperty=fullName>, <xref:System.Runtime.CompilerServices.NullablePublicOnlyAttribute?displayProperty=fullName> | These attributes encode nullable annotations in your source code. |
49+
| <xref:System.ParamArrayAttribute?displayProperty=fullName> | This attribute encodes the `params` modifier on array parameters. |
50+
| <xref:System.Runtime.CompilerServices.ParamCollectionAttribute?displayProperty=fullName> | This attribute encodes the `params` modifier on non-array parameters. |
51+
| <xref:System.Runtime.CompilerServices.RefSafetyRulesAttribute?displayProperty=fullName> | This attribute specifies the C# version that is required in order to understand ref safety annotations in the assembly. Ref safety rules evolve as C# gets new features. |
52+
| <xref:System.Runtime.CompilerServices.RequiredMemberAttribute?displayProperty=fullName> | This attribute indicates that the `required` modifier was placed on a member declaration. It's the encoding of the [required members](../keywords/required.md) language feature. |
53+
| <xref:System.Runtime.CompilerServices.TupleElementNamesAttribute?displayProperty=fullName> | This attribute encodes tuple element names used in signatures. |
54+
55+
In addition, the compiler can generate a declaration for other attributes used internally. The compiler generates these in the <xref:System.Runtime.CompilerServices> namespace for its own use. Some aren't in the .NET Runtime libraries. Instead, the compiler synthesizes a definition for an `internal` type declaration in any assembly where the attribute is needed.

docs/csharp/language-reference/toc.yml

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -380,17 +380,35 @@ items:
380380
- name: Attributes read by the compiler
381381
items:
382382
- name: Global attributes
383-
displayName: AssemblyName, AssemblyVersion, AssemblyCulture, AssemblyFlags, AssemblyProduct, AssemblyTrademark, AssemblyInformationalVersion, AssemblyCompany, AssemblyCopyright, AssemblyFileVersion, CLSCompliant, AssemblyTitle, AssemblyDescription, AssemblyConfiguration, AssemblyDefaultAlias
383+
displayName: >
384+
AssemblyName, AssemblyVersion, AssemblyCulture, AssemblyFlags, AssemblyProduct, AssemblyTrademark, AssemblyInformationalVersion,
385+
AssemblyCompany, AssemblyCopyright, AssemblyFileVersion, CLSCompliant, AssemblyTitle, AssemblyDescription, AssemblyConfiguration,
386+
AssemblyDefaultAlias
384387
href: ./attributes/global.md
385388
- name: Caller information
386-
displayName: CallerFilePath, CallerLineNumber, CallerMemberName
389+
displayName: CallerFilePath, CallerLineNumber, CallerMemberName, CallerArgumentExpressionAttribute
387390
href: ./attributes/caller-information.md
388391
- name: Nullable static analysis
389-
displayName: AllowNull, DisallowNull, MaybeNull, NotNull, MaybeNullWhen, NotNullWhen, NotNullIfNotNull, DoesNotReturn, DoesNotReturnIf
392+
displayName: >
393+
AllowNull, DisallowNull, MaybeNull, NotNull, MaybeNullWhen, NotNullWhen, NotNullIfNotNull, MemberNotNull, MemberNotNullIf,
394+
DoesNotReturn, DoesNotReturnIf
390395
href: ./attributes/nullable-analysis.md
391396
- name: Miscellaneous
392-
displayName: Conditional, Obsolete, Experimental, SetsRequiredMembers, AttributeUsage, ModuleInitializer, SkipLocalsInit, module initializer
397+
displayName: >
398+
Conditional, Obsolete, Deprecated, Experimental, SetsRequiredMembers, AttributeUsage, AsyncMethodBuilder, InterpolatedStringHandler,
399+
ModuleInitializer, SkipLocalsInit, UnscopedRef, OverloadResolutionPriority. EnumeratorCancellation, CollectionBuilder,
400+
IUnknownConstant, IDispatchConstant, module initializer
393401
href: ./attributes/general.md
402+
- name: Pseudo-attributes
403+
displayName: >
404+
ComImportAttribute, DllImportAttribute, FieldOffsetAttribute, MarshalAsAttribute, MethodImplAttribute, NonSerializedAttribute,
405+
OptionalAttribute, OutAttribute, PreserveSigAttribute, SerializableAttribute, StructLayoutAttribute, IndexerNameAttribute,
406+
DefaultParameterValueAttribute, InAttribute, SpecialNameAttribute, UnmanagedCallersOnlyAttribute, CompilerFeatureRequiredAttribute,
407+
DecimalConstantAttribute, DefaultMemberAttribute, DynamicAttribute, ExtensionAttribute, FixedBufferAttribute, IsByRefLikeAttribute,
408+
IsReadOnlyAttribute, RequiresLocationAttribute, IsUnmanagedAttribute, NullableAttribute, NullableContextAttribute,
409+
NullablePublicOnlyAttribute, ParamArrayAttribute, ParamCollectionAttribute, RefSafetyRulesAttribute, RequiredMemberAttribute,
410+
TupleElementNamesAttribute
411+
href: ./attributes/pseudo-attributes.md
394412
- name: Unsafe code and pointers
395413
displayName: unsafe code, pointers, fixed size buffer, function pointer
396414
href: ./unsafe-code.md

0 commit comments

Comments
 (0)