From 3831646c746be4fc74b5cfbfdb525678de29ed41 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 2 Mar 2026 08:17:06 -0500 Subject: [PATCH 1/2] 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 ba26b5c0d..e386b05f6 100644 --- a/standard/classes.md +++ b/standard/classes.md @@ -263,7 +263,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.5.5](basic-concepts.md#755-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 b16873cef2049ab4da7cb6f44f0672b0a469fe84 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Fri, 1 May 2026 17:43:28 -0400 Subject: [PATCH 2/2] Add additional text A couple other locations needed updates for generic attribute classes. --- standard/attributes.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/standard/attributes.md b/standard/attributes.md index 9384f8602..0ceb1b33b 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,6 +64,8 @@ The attribute `AttributeUsage` ([§23.5.2](attributes.md#2352-the-attributeusage `AttributeUsage` 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. +> *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: > >