From 914884f92919ac228578b4b958ba31e6b463610e Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Sat, 17 Apr 2021 11:11:37 -0400 Subject: [PATCH 1/4] Allow field-targeted attributes on auto-property declarations --- standard/classes.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/standard/classes.md b/standard/classes.md index c5f5cf566..5c05a1665 100644 --- a/standard/classes.md +++ b/standard/classes.md @@ -3447,6 +3447,34 @@ An auto-property may optionally have a *property_initializer*, which is applied > > *end example* +Although the backing field is hidden, that field may have field-targeted attributes applied directly to it via the automatically implemented property's *property_declaration* ([§14.7.1](classes.md#1471-general)). + +> *Example*: The following code +> +> ```csharp +> public class Foo +> { +> [field: NonSerialized] +> public string MySecret { get; set; } +> } +> ``` +> results in the field-targeted attribute `NonSerialized` being applied to the compiler-generated backing field, as if the code had been written as follows: +> ```csharp +> [Serializable] +> public class Foo +> { +> [NonSerialized] +> private string _mySecretBackingField; +> public string MySecret +> { +> get { return _mySecretBackingField; } +> set { _mySecretBackingField = value; } +> } +> } +> ``` +> +> *end example* + ### 14.7.5 Accessibility If an accessor has an *accessor_modifier*, the accessibility domain ([§7.5.3](basic-concepts.md#753-accessibility-domains)) of the accessor is determined using the declared accessibility of the *accessor_modifier*. If an accessor does not have an *accessor_modifier*, the accessibility domain of the accessor is determined from the declared accessibility of the property or indexer. From 2c551e451100792acaa84a53bb746d3aca612ea4 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Sun, 3 Apr 2022 15:28:19 -0400 Subject: [PATCH 2/4] fix lint warnigns --- standard/classes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/standard/classes.md b/standard/classes.md index 5c05a1665..60f2dd3cb 100644 --- a/standard/classes.md +++ b/standard/classes.md @@ -3458,7 +3458,9 @@ Although the backing field is hidden, that field may have field-targeted attribu > public string MySecret { get; set; } > } > ``` +> > results in the field-targeted attribute `NonSerialized` being applied to the compiler-generated backing field, as if the code had been written as follows: +> > ```csharp > [Serializable] > public class Foo From a14d97c29cf5151e1b3d991ee55293583c6b78a5 Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Tue, 3 Jan 2023 16:46:39 +0000 Subject: [PATCH 3/4] Make field-targeted attribute example self-consistent --- standard/classes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/standard/classes.md b/standard/classes.md index 60f2dd3cb..111519e82 100644 --- a/standard/classes.md +++ b/standard/classes.md @@ -3452,6 +3452,7 @@ Although the backing field is hidden, that field may have field-targeted attribu > *Example*: The following code > > ```csharp +> [Serializable] > public class Foo > { > [field: NonSerialized] From ab777da743ee4f11d6ba359dbab13908ea7ea3b1 Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Tue, 3 Jan 2023 17:40:00 +0000 Subject: [PATCH 4/4] Modify attribute targeting description for field-targeted autoprop attributes --- standard/attributes.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/standard/attributes.md b/standard/attributes.md index 46ba1226c..4acc2d781 100644 --- a/standard/attributes.md +++ b/standard/attributes.md @@ -275,7 +275,7 @@ No other values for *global_attribute_target* are allowed. The standardized *attribute_target* names are `event`, `field`, `method`, `param`, `property`, `return`, `type`, and `typevar`. These target names shall only be used in the following contexts: - `event` — an event. -- `field` — a field. A field-like event (i.e., one without accessors) can also have an attribute with this target. +- `field` — a field. A field-like event (i.e., one without accessors) ([§14.8.2](classes.md#1482-field-like-events)) and an automatically implemented property ([§14.7.4](classes.md#1474-automatically-implemented-properties)) can also have an attribute with this target. - `method` — a constructor, finalizer, method, operator, property get and set accessors, indexer get and set accessors, and event add and remove accessors. A field-like event (i.e., one without accessors) can also have an attribute with this target. - `param` — a property set accessor, an indexer set accessor, event add and remove accessors, and a parameter in a constructor, method, and operator. - `property` — a property and an indexer. @@ -300,6 +300,8 @@ Certain contexts permit the specification of an attribute on more than one targe - For an attribute specified on a set accessor for a property or indexer declaration the default target is the associated method. Otherwise when the *attribute_target* is equal to: - `method` — the target is the associated method - `param` — the target is the lone implicit parameter +- For an attribute on an automatically implemented property declaration the default target is the property. Otherwise when the *attribute_target* is equal to: + - `field` — the target is the compiler-generated backing field for the property - For an attribute specified on an event declaration that omits *event_accessor_declarations* the default target is the event declaration. Otherwise when the *attribute_target* is equal to: - `event` — the target is the event declaration - `field` — the target is the field