Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions standard/attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@

## 23.3 Attribute specification

Application of a previously defined attribute to a program entity is called ***attribute specification***. An attribute is a piece of additional declarative information that is specified for a program entity. Attributes can be specified at global scope (to specify attributes on the containing assembly or module) and for *type_declaration*s ([§14.7](namespaces.md#147-type-declarations)), *class_member_declaration*s ([§15.3](classes.md#153-class-members)), *interface_member_declaration*s ([§19.4](interfaces.md#194-interface-members)), *struct_member_declaration*s ([§16.3](structs.md#163-struct-members)), *enum_member_declaration*s ([§20.2](enums.md#202-enum-declarations)), *accessor_declaration*s ([§15.7.3](classes.md#1573-accessors)), *event_accessor_declaration*s ([§15.8](classes.md#158-events)), elements of *parameter_list*s ([§15.6.2](classes.md#1562-method-parameters)), and elements of *type_parameter_list*s ([§15.2.3](classes.md#1523-type-parameters)).
Application of a previously defined attribute to a program entity is called ***attribute specification***. An attribute is a piece of additional declarative information that is specified for a program entity. Attributes can be specified at global scope (to specify attributes on the containing assembly or module) and for *type_declaration*s ([§14.7](namespaces.md#147-type-declarations)), *class_member_declaration*s ([§15.3](classes.md#153-class-members)), *interface_member_declaration*s ([§19.4](interfaces.md#194-interface-members)), *struct_member_declaration*s ([§16.3](structs.md#163-struct-members)), *enum_member_declaration*s ([§20.2](enums.md#202-enum-declarations)), *accessor_declaration*s ([§15.7.3](classes.md#1573-accessors)), *event_accessor_declaration*s ([§15.8](classes.md#158-events)), elements of *parameter_list*s ([§15.6.2](classes.md#1562-method-parameters)), elements of *type_parameter_list*s ([§15.2.3](classes.md#1523-type-parameters)), *lambda_expression*s ([§12.22.1](expressions.md#12221-general)), and elements of *explicit_anonymous_function_parameter*s and *implicit_anonymous_function_parameter*s ([§12.22.1](expressions.md#12221-general)).

Attributes are specified in ***attribute section***s. An attribute section consists of a pair of square brackets, which surround a comma-separated list of one or more attributes. The order in which attributes are specified in such a list, and the order in which sections attached to the same program entity are arranged, is not significant. For instance, the attribute specifications `[A][B]`, `[B][A]`, `[A, B]`, and `[B, A]` are equivalent.

Expand Down Expand Up @@ -252,10 +252,10 @@

- `event` — an event.
- `field` — a field. A field-like event (i.e., one without accessors) ([§15.8.2](classes.md#1582-field-like-events)) and an automatically implemented property ([§15.7.4](classes.md#1574-automatically-implemented-properties)) can also have an attribute with this target.
- `method` — a constructor; finalizer; method; operator; property get, set, and init accessors; indexer get, set, and init accessors; and event add and remove accessors. A field-like event (i.e., one without accessors) can also have an attribute with this target.
- `method` — a constructor; finalizer; method; operator; property get, set, and init accessors; indexer get, set, and init accessors; event add and remove accessors; and lambda expressions. A field-like event (i.e., one without accessors) can also have an attribute with this target.
- `param` — property set and init accessors, indexer set and init accessors, event add and remove accessors, and a parameter in a constructor, method, and operator.
- `property` — a property and an indexer.
- `return` — a delegate, method, operator, property get accessor, and indexer get accessor.
- `return` — a delegate, method, operator, property get accessor, indexer get accessor, and lambda expression.
- `type` — a delegate, class, struct, enum, and interface.
- `typevar` — a type parameter.

Expand Down Expand Up @@ -285,6 +285,9 @@
- In the case of an event declaration that does not omit *event_accessor_declarations* the default target is the method.
- `method` — the target is the associated method
- `param` — the target is the lone parameter
- For an attribute on a *lambda_expression* the default target is the method. Otherwise when the *attribute_target* is equal to:
- `method` — the target is the method
- `return` — the target is the return value

In all other contexts, inclusion of an *attribute_target_specifier* is permitted but unnecessary.

Expand Down Expand Up @@ -967,7 +970,7 @@
> ```csharp
> #nullable enable
> public class X
> {

Check warning on line 973 in standard/attributes.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/attributes.md#L973

MDC032::Line length 86 > maximum 81
> private void ThrowIfNull([DoesNotReturnIf(true)] bool isNull, string argumentName)
> {
> if (isNull)
Expand Down Expand Up @@ -1193,4 +1196,4 @@
>
> *end example*


Check failure on line 1199 in standard/attributes.md

View workflow job for this annotation

GitHub Actions / lint

Multiple consecutive blank lines

standard/attributes.md:1199 MD012/no-multiple-blanks Multiple consecutive blank lines [Expected: 1; Actual: 2] https://github.com/DavidAnson/markdownlint/blob/v0.40.0/doc/md012.md
45 changes: 44 additions & 1 deletion standard/conversions.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
- Implicit tuple conversions ([§10.2.13](conversions.md#10213-implicit-tuple-conversions))
- Default literal conversions ([§10.2.16](conversions.md#10216-default-literal-conversions))
- Implicit throw conversions ([§10.2.17](conversions.md#10217-implicit-throw-conversions))
- Anonymous function type conversions (§anon-func-type-conversion)

Implicit conversions can occur in a variety of situations, including function member invocations ([§12.6.6](expressions.md#1266-function-member-invocation)), cast expressions ([§12.9.8](expressions.md#1298-cast-expressions)), and assignments ([§12.24](expressions.md#1224-assignment-operators)).

Expand Down Expand Up @@ -376,7 +377,7 @@

### 10.2.15 Anonymous function conversions and method group conversions

Anonymous functions and method groups do not have types in and of themselves, but they may be implicitly converted to delegate types. Additionally, some lambda expressions may be implicitly converted to expression tree types. Anonymous function conversions are described in more detail in [§10.7](conversions.md#107-anonymous-function-conversions) and method group conversions in [§10.8](conversions.md#108-method-group-conversions).
Anonymous functions and method groups do not have types in and of themselves, but they may have a natural type (§anon-func-type). They may be implicitly converted to delegate types. Additionally, some lambda expressions may be implicitly converted to expression tree types. Anonymous function conversions are described in more detail in [§10.7](conversions.md#107-anonymous-function-conversions) and method group conversions in [§10.8](conversions.md#108-method-group-conversions).

### 10.2.16 Default literal conversions

Expand Down Expand Up @@ -405,6 +406,47 @@

an implicit ***conditional expression conversion*** exists that permits an implicit conversion from *conditional_expression* to any type `T` for which there is a conversion-from-expression from `e1` to `T` and also from `e2` to `T`. It is an error if *conditional_expression* neither has a common type between `e1` and `e2` nor is subject to a conditional expression conversion.

### §anon-func-type-conversion Anonymous function type conversion

The following conversions are permitted from an anonymous function type `F`(§anon-func-type):

- To an anonymous function type `G` if the parameters and return types of `F` are variance-convertible to the parameters and return type of `G`.
- To `System.Delegate` or its base classes or interfaces.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The MS proposal mentions System.MulticastDelegate. However, as we don’t have that type in our spec, I replaced all such mentions with System.Delegate.

- To `System.Linq.Expressions.Expression` or `System.Linq.Expressions.LambdaExpression`.

There are no conversions to an anonymous function type from a type other than an anonymous function type.

A conversion to `System.Delegate` or its base classes or interfaces realizes the anonymous function or method group as an instance of an appropriate delegate type.

A conversion to `System.Linq.Expressions.Expression<TDelegate>` or its base classes realizes the anonymous function or method group as an expression tree with an appropriate delegate type.

> *Example*:
>
> <!-- Example: {template:"standalone-console", name: "AnonFuncTypeConv1", ignoredWarnings:["CS8974"]} -->
> ```csharp
> Delegate d = delegate (object obj) { }; // Action<object>
> Expression e = () => ""; // Expression<Func<string>>
> object o = "".Clone; // Func<object>
> ```
>
> *end example*

Anonymous function type conversions are not implicit or explicit standard conversions and are not considered when determining whether a user-defined conversion operator is applicable to an anonymous function or method group.

Although an implicit conversion to `object` is permitted, a warning shall be issued, as this may have been unintentional.

> *Example*:
>
> <!-- Example: {template:"standalone-console", name: "AnonFuncTypeConv2", ignoredWarnings:["CS8974"]} -->
> ```csharp
> Random r = new Random();
> object obj;
> obj = r.NextDouble; // warning: was this intentional?
> obj = (object)r.NextDouble; // ok
> ```
>
> *end example*

## 10.3 Explicit conversions

### 10.3.1 General
Expand Down Expand Up @@ -814,7 +856,7 @@
>
> var amt6 = 66036; // var types amt6 as int
> var dose6 = (Dose)amt6; // amt3 is int, int to ushort conversion added
> // warning as information loss may occur

Check warning on line 859 in standard/conversions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/conversions.md#L859

MDC032::Line length 82 > maximum 81
> Console.WriteLine(dose6); // outputs 500mg, not 66036mg, due to information loss
>
> // Using a constructor instead of user-defined conversion:
Expand Down Expand Up @@ -880,6 +922,7 @@
- If `F` does not contain an *anonymous_function_signature*, then `D` may have zero or more parameters of any type, as long as no parameter of `D` is an output parameter.
- If `F` has an explicitly typed parameter list, each parameter in `D` has the same modifiers as the corresponding parameter in `F` and an identity conversion exists between the corresponding parameter in `F`.
- If `F` has an implicitly typed parameter list, `D` has no reference or output parameters.
- If `F` has an explicit return type, an identity conversion shall exist from the return type of `F` to the return type of `D`.
- If the body of `F` is an expression, and *either* `D` has a void return type *or* `F` is async and `D` has a `«TaskType»` return type ([§15.14.1](classes.md#15141-general)), then when each parameter of `F` is given the type of the corresponding parameter in `D`, the body of `F` is a valid expression (w.r.t [§12](expressions.md#12-expressions)) that would be permitted as a *statement_expression* ([§13.7](statements.md#137-expression-statements)).
- If the body of `F` is a block, and *either* `D` has a void return type *or* `F` is async and `D` has a `«TaskType»` return type , then when each parameter of `F` is given the type of the corresponding parameter in `D`, the body of `F` is a valid block (w.r.t [§13.3](statements.md#133-blocks)) in which no `return` statement specifies an expression.
- If the body of `F` is an expression, and *either* `F` is non-async and `D` has a non-`void` return type `T`, *or* `F` is async and `D` has a `«TaskType»<T>` return type ([§15.14.1](classes.md#15141-general)), then when each parameter of `F` is given the type of the corresponding parameter in `D`, the body of `F` is a valid expression (w.r.t [§12](expressions.md#12-expressions)) that is implicitly convertible to `T`.
Expand Down
Loading
Loading