From fe212e61d851b649616c19f69ab1e5a8d6f55bf5 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 2 Mar 2026 08:17:06 -0500 Subject: [PATCH 1/4] support generic attributes --- standard/classes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/classes.md b/standard/classes.md index 12e4484cf..97488a5f2 100644 --- a/standard/classes.md +++ b/standard/classes.md @@ -247,7 +247,7 @@ The base class specified in a class declaration can be a constructed class type The direct base class of a class type shall be at least as accessible as the class type itself ([§7.4.5](basic-concepts.md#745-accessibility-constraints)). For example, it is a compile-time error for a public class to derive from a private or internal class. -The direct base class of a class type shall not be any of the following types: `System.Array`, `System.Delegate`, `System.Enum`, `System.ValueType` or the `dynamic` type. Furthermore, a generic class declaration shall not use `System.Attribute` as a direct or indirect base class ([§23.2.1](attributes.md#2321-general)). +The direct base class of a class type shall not be any of the following types: `System.Array`, `System.Delegate`, `System.Enum`, `System.ValueType` or the `dynamic` type. In determining the meaning of the direct base class specification `A` of a class `B`, the direct base class of `B` is temporarily assumed to be `object`, which ensures that the meaning of a base class specification cannot recursively depend on itself. Given this definition, the complete set of types upon which a class depends is the transitive closure of the *directly depends on* relationship. From 6980c0cb8d87fca110732e763cec182d41e81f50 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Fri, 1 May 2026 17:43:28 -0400 Subject: [PATCH 2/4] Add additional text A couple other locations needed updates for generic attribute classes. --- standard/attributes.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/standard/attributes.md b/standard/attributes.md index 150df7494..0f06525ce 100644 --- a/standard/attributes.md +++ b/standard/attributes.md @@ -16,14 +16,17 @@ Attributes are defined through the declaration of attribute classes ([§23.2](at A class that derives from the abstract class `System.Attribute`, whether directly or indirectly, is an ***attribute class***. The declaration of an attribute class defines a new kind of attribute that can be placed on program entities. By convention, attribute classes are named with a suffix of `Attribute`. Uses of an attribute may either include or omit this suffix. -A generic class declaration shall not use `System.Attribute` as a direct or indirect base class. +An attribute class may be generic. When an *attribute_name* references a generic attribute class, each type argument is subject to the same restrictions that apply to a type argument of the `typeof` operator ([§12.8.18](expressions.md#12818-the-typeof-operator)); for example, `dynamic`, a tuple type with element names, a nullable reference type, `nint`, and `nuint` are not permitted as type arguments. (In addition, a type parameter of the surrounding declaration shall not be used as a type argument; see §8.5.) > *Example*: > -> +> > ```csharp -> public class B : Attribute {} -> public class C : B {} // Error – generic cannot be an attribute +> using System; +> public class Attr : Attribute { } // OK – generic attribute class +> +> [Attr] // OK +> public class C1 { } > ``` > > *end example* @@ -61,7 +64,9 @@ The attribute `AttributeUsageAttribute` ([§23.5.2](attributes.md#2352-the-attri `AttributeUsageAttribute` has a named parameter ([§23.2.3](attributes.md#2323-positional-and-named-parameters)), called `AllowMultiple`, which indicates whether the attribute can be specified more than once for a given entity. If `AllowMultiple` for an attribute class is true, then that attribute class is a ***multi-use attribute class***, and can be specified more than once on an entity. If `AllowMultiple` for an attribute class is false or it is unspecified, then that attribute class is a ***single-use attribute class***, and can be specified at most once on an entity. -> *Example*: The following example defines a multi-use attribute class named `AuthorAttribute` and shows a class declaration with two uses of the attribute: +> *Note*: For a generic attribute class, multiplicity is determined by the unbound generic attribute class definition, not by individual closed constructions. Therefore, when `AllowMultiple` is false or unspecified, two attribute applications that differ only in their type arguments shall not both appear on the same entity. *end note* + +> *Example*: The following example defines a multi-use attribute class named `AuthorAttribute` and shows a class declaration with two uses of the `Author` attribute: > > > From fb9fcc9052d53423b2c2b8d7faba18988c21cc9e Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Fri, 18 Sep 2026 17:13:24 -0400 Subject: [PATCH 3/4] Fix generic-attribute blockquote lint --- standard/attributes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/standard/attributes.md b/standard/attributes.md index 0f06525ce..5972cf69d 100644 --- a/standard/attributes.md +++ b/standard/attributes.md @@ -66,6 +66,8 @@ The attribute `AttributeUsageAttribute` ([§23.5.2](attributes.md#2352-the-attri > *Note*: For a generic attribute class, multiplicity is determined by the unbound generic attribute class definition, not by individual closed constructions. Therefore, when `AllowMultiple` is false or unspecified, two attribute applications that differ only in their type arguments shall not both appear on the same entity. *end note* + + > *Example*: The following example defines a multi-use attribute class named `AuthorAttribute` and shows a class declaration with two uses of the `Author` attribute: > > From 9dc5cbf1e91b4fdef8db62c089aa1b07634d48e1 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Mon, 21 Sep 2026 14:59:44 -0400 Subject: [PATCH 4/4] Remove duplicate generic attribute using directive Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bce5e82a-89fd-4655-bc08-6d6ba97f0cc6 --- standard/attributes.md | 1 - 1 file changed, 1 deletion(-) diff --git a/standard/attributes.md b/standard/attributes.md index 5972cf69d..0d9346a94 100644 --- a/standard/attributes.md +++ b/standard/attributes.md @@ -22,7 +22,6 @@ An attribute class may be generic. When an *attribute_name* references a generic > > > ```csharp -> using System; > public class Attr : Attribute { } // OK – generic attribute class > > [Attr] // OK