diff --git a/standard/delegates.md b/standard/delegates.md index 2d07ecfa5..87cab7065 100644 --- a/standard/delegates.md +++ b/standard/delegates.md @@ -79,7 +79,6 @@ A method or delegate type `M` is ***compatible*** with a delegate type `D` if al - `D` and `M` have the same number of parameters, and each parameter in `D` has the same `ref` or `out` modifiers as the corresponding parameter in `M`. - For each value parameter (a parameter with no `ref` or `out` modifier), an identity conversion ([§10.2.2](conversions.md#1022-identity-conversion)) or implicit reference conversion ([§10.2.8](conversions.md#1028-implicit-reference-conversions)) exists from the parameter type in `D` to the corresponding parameter type in `M`. - - For each `ref` or `out` parameter, the parameter type in `D` is the same as the parameter type in `M`. - An identity or implicit reference conversion exists from the return type of `M` to the return type of `D`. diff --git a/standard/expressions.md b/standard/expressions.md index e5c079097..55a5be441 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -945,34 +945,34 @@ In case the parameter type sequences `{P₁, P₂, ..., Pᵥ}` and `{Q₁, Q₂ #### 11.6.4.4 Better conversion from expression -Given an implicit conversion `C₁` that converts from an expression `E` to a type `T₁`, and an implicit conversion `C₂` that converts from an expression `E` to a type `T₂`, `C₁` is a ***better conversion*** than `C₂` if at least one of the following holds: +Given an implicit conversion `C₁` that converts from an expression `E` to a type `T₁`, and an implicit conversion `C₂` that converts from an expression `E` to a type `T₂`, `C₁` is a better conversion than `C₂` if one of the following holds: -- `E` has a type `S` and an identity conversion exists from `S` to `T₁` but not from `S` to `T₂` -- `E` is not an anonymous function and `T₁` is a better conversion target than `T₂` ([§11.6.4.6](expressions.md#11646-better-conversion-target)) -- `E` is an anonymous function, `T₁` is either a delegate type `D₁` or an expression tree type `Expression`, `T₂` is either a delegate type `D₂` or an expression tree type `Expression` and one of the following holds: - - `D₁` is a better conversion target than `D₂` - - `D₁` and `D₂` have identical parameter lists, and one of the following holds: - - `D₁` has a return type `Y₁`, and `D₂` has a return type `Y₂`, an inferred return type `X` exists for `E` in the context of that parameter list ([§11.6.3.13](expressions.md#116313-inferred-return-type)), and the conversion from `X` to `Y₁` is better than the conversion from `X` to `Y₂` - - `E` is async, `D₁` has a return type `Task`, and `D₂` has a return type `Task`, an inferred return type `Task` exists for `E` in the context of that parameter list ([§11.6.3.13](expressions.md#116313-inferred-return-type)), and the conversion from `X` to `Y₁` is better than the conversion from `X` to `Y₂` - - `D₁` has a return type `Y`, and `D₂` is void returning +- `E` exactly matches `T₁` and `E` does not exactly match `T₂` (§11.6.4.5) +- `E` exactly matches both or neither of `T₁` and `T₂`, and `T₁` is a better conversion target than `T₂` (§11.6.4.6) -#### 11.6.4.5 Better conversion from type +#### 11.6.4.5 Exactly matching expression -Given a conversion `C₁` that converts from a type `S` to a type `T₁`, and a conversion `C₂` that converts from a type `S` to a type `T₂`, `C₁` is a *better conversion* than `C₂` if at least one of the following holds: +Given an expression `E` and a type `T`, `E` ***exactly matches*** `T` if one of the following holds: -- An identity conversion exists from `S` to `T₁` but not from `S` to `T₂` -- `T₁` is a better conversion target than `T₂` ([§11.6.4.6](expressions.md#11646-better-conversion-target)) +- `E` has a type `S`, and an identity conversion exists from `S` to `T` +- `E` is an anonymous function, `T` is either a delegate type `D` or an expression tree type `Expression` and one of the following holds: + - An inferred return type `X` exists for `E` in the context of the parameter list of `D` (§11.6.3.12), and an identity conversion exists from `X` to the return type of `D` + - Either `E` is non-async and `D` has a return type `Y` or `E` is async and `D` has a return type `Task`, and one of the following holds: + - The body of `E` is an expression that exactly matches `Y` + - The body of `E` is a statement block where every return statement returns an expression that exactly matches `Y` #### 11.6.4.6 Better conversion target -Given two different types `T₁` and `T₂`, `T₁` is a better conversion target than `T₂` if at least one of the following holds: +Given an expression `E` and two types `T₁` and `T₂`, `T₁` is a ***better conversion target*** than `T₂` for `E` if one of the following holds: -- An implicit conversion from `T₁` to `T₂` exists, and no implicit conversion from `T₂` to `T₁` exists -- `T₁` is a signed integral type and `T₂` is an unsigned integral type. Specifically: - - `T₁` is `sbyte` and `T₂` is `byte`, `ushort`, `uint`, or `ulong` - - `T₁` is `short` and `T₂` is `ushort`, `uint`, or `ulong` - - `T₁` is `int` and `T₂` is `uint`, or `ulong` - - `T₁` is `long` and `T₂` is `ulong` +- An implicit conversion from `T₁` to `T₂` exists +- `T₁` is `Task`, `T₂` is `Task`, and `S₁` is a better conversion target than `S₂` +- `T₁` is `S₁` or `S₁?` where `S₁` is a signed integral type, and `T₂` is `S₂` or `S₂?` where `S₂` is an unsigned integral type. Specifically: + - `S₁` is `sbyte` and `S₂` is `byte`, `ushort`, `uint`, or `ulong` + - `S₁` is `short` and `S₂` is `ushort`, `uint`, or `ulong` + - `S₁` is `int` and `S₂` is `uint`, or `ulong` + - `S₁` is `long` and `S₂` is `ulong` +- `E` is a method group conversion (§10.8() and `T₁` is compatible (§19.4) with the single best method from the method group #### 11.6.4.7 Overloading in generic classes