From ca9b8141ebeb37eda4f02baec8c8ace0f24620af Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Tue, 18 Aug 2026 11:48:09 -0400 Subject: [PATCH] [alpha-v13] Alpha feature preview PR #1772: Feature support for Better conversion Source: https://github.com/dotnet/csharpstandard/pull/1772 Head SHA: 3ff0a5f7d864e57ac6aedd9f061ad678af4a6e5a Apply better conversion feature patch from PR #1772 to alpha-v13. 1 file modified: expressions.md --- standard/expressions.md | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/standard/expressions.md b/standard/expressions.md index 63750adbe..6a93d418d 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -1183,10 +1183,7 @@ Given `int i = 10;`, according to [§12.6.4.2](expressions.md#12642-applicable-f 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` is a *collection_expression* and one of the following holds: - - `T₁` is `System.ReadOnlySpan`, and `T₂` is `System.Span`, and an implicit conversion exists from `E₁` to `E₂`. - - `T₁` is `System.ReadOnlySpan` or `System.Span`, and `T₂` is an *array_type*, or one of the following interface types implemented by an *array_type*: `System.Collections.Generic.IEnumerable`, `System.Collections.Generic.IReadOnlyCollection`, `System.Collections.Generic.IReadOnlyList`, `System.Collections.Generic.ICollection`, or `System.Collections.Generic.IList` with element type `E₂`, and an implicit conversion exists from `E₁` to `E₂`. - - `T₁` and `T₂` are not `System.ReadOnlySpan` or `System.Span`, and an implicit conversion exists from `T₁` to `T₂`. +- `E` is a *collection_expression* and `C₁` is a better collection conversion from expression than `C₂` (see definition below): - `E` is not a *collection_expression* and one of the following holds: - `E` is a non-constant *interpolated_string_expression*, `C₁` is an implicit interpolated string handler conversion, `T₁` is an applicable interpolated string handler type, and `C₂` is not an implicit interpolated string handler conversion. - `C₁` is not a *function_type_conversion* and `C₂` is a *function_type_conversion*. @@ -1198,6 +1195,34 @@ Given an implicit conversion `C₁` that converts from an expression `E` to a ty > *Note*: This is only applicable in unsafe code. *end note* - `E` is a method group ([§12.2](expressions.md#122-expression-classifications)), `T₁` is compatible ([§21.4](delegates.md#214-delegate-compatibility)) with the single best method from the method group for conversion `C₁`, and `T₂` is not compatible with the single best method from the method group for conversion `C₂`. +Given the following: + +- `E` is a collection expression with element expressions `[EL₁, EL₂, ..., ELₙ]` +- `T₁` and `T₂` are collection types +- `E₁` is the element type of `T₁` +- `E₂` is the element type of `T₂` +- `CE₁ᵢ` are the series of conversions from `ELᵢ` to `E₁` +- `CE₂ᵢ` are the series of conversions from `ELᵢ` to `E₂` + +If there is an identity conversion from `E₁` to `E₂`, then the element conversions are as good as each other. Otherwise, the element conversions to `E₁` are ***better than the element conversions*** to `E₂` if: + +- For every `ELᵢ`, `CE₁ᵢ` is at least as good as `CE₂ᵢ`, and +- There is at least one i where `CE₁ᵢ` is better than `CE₂ᵢ` + +Otherwise, neither set of element conversions is better than the other, and they are also not as good as each other. + +Conversion comparisons are made using better conversion from expression if `ELᵢ` is not a spread element. If `ELᵢ` is a spread element, use better conversion from the element type of the spread collection to `E₁` or `E₂`, respectively. + +`C₁` is a ***better collection conversion from expression*** than `C₂` if: + +- Both `T₁` and `T₂` are not *span types*, and `T₁` is implicitly convertible to `T₂`, and `T₂` is not implicitly convertible to `T₁`, or +- `E₁` does not have an identity conversion to `E₂`, and the element conversions to `E₁` are ***better than the element conversions*** to `E₂`, or +- `E₁` has an identity conversion to `E₂`, and one of the following holds: + - `T₁` is `System.ReadOnlySpan`, and `T₂` is `System.Span`, or + - `T₁` is `System.ReadOnlySpan` or `System.Span`, and `T₂` is an *array_or_array_interface* with *element type* `E₂` + +Otherwise, neither collection type is better, and the result is ambiguous. + > *Example*: The following example shows the differences with overload resolution between array initializers and collection expressions: > >