-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Collection expression arguments: open questions #9158
Changes from 4 commits
287f082
c837efb
3af4fd1
1ec2b68
e9cc48f
74f6d2b
5942f56
b7c4f72
0d5e1f2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -523,6 +523,60 @@ This concern already exists with *collection types*. For those types, the rule | |||||
|
||||||
## Open Questions | ||||||
|
||||||
### Binding to indexer | ||||||
|
||||||
For concrete dictionary types that do not use `CollectionBuilderAttribute`, where the compiler constructs the resulting instance using a constructor and repeated calls to an indexer, how should the compiler resolve the appropriate indexer for each element? | ||||||
|
||||||
Options include: | ||||||
1. For each element individually, use normal lookup rules and overload resolution to determine the resulting indexer based on the element expression (for an expression element) or type (for a spread or key-value pair element). *This corresponds to the binding behavior for `Add()` methods for non-dictionary collection expressions.* | ||||||
2. Use the target type implementation of `IDictionary<K, V>.this[K] { get; set; }`. | ||||||
3. Use the accessible indexer that matches the signature `V this[K] { get; set; }`. | ||||||
|
||||||
### `dynamic` elements | ||||||
|
||||||
Related to the previous question, how should the compiler bind to the indexer when the element expression has `dynamic` type, or when either the key or value is `dynamic`? | ||||||
|
||||||
For reference, with non-dictionary targets, an element with `dynamic` type, the compiler binds to the applicable `Add(value)` method at runtime. | ||||||
|
||||||
For dictionary targets, the situtation is more complicated because we have key-value pairs to consider. ... | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks. I've since removed the question about |
||||||
|
||||||
There is a related question of *key-value pair conversions* (see below). If we allow dynamic conversion of key or value independently, then we're essentially supporting key-value pair conversions at runtime. If that's the case, we'll probably want to key-value pair conversions at compile-time for non-`dynamic` cases. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
```csharp | ||||||
KeyValuePair<int, string> x = new(1, "one"); | ||||||
KeyValuePair<dynamic, string> y = new(2, "two"); | ||||||
|
||||||
Dictionary<long, string> d; | ||||||
d = [x]; // compile-time key-value pair conversion from int to long? | ||||||
d = [y]; // runtime conversion from dynamic to long? | ||||||
``` | ||||||
|
||||||
Options include: | ||||||
1. No support for dynamic conversion of the element expression, or of key or value. | ||||||
2. Rewrite dynamic conversion from element expressions as explicit conversion to element typee. | ||||||
3. Allow dynamic conversion of element expression, and of key or value. | ||||||
|
||||||
### Key-value pair conversions | ||||||
|
||||||
Should the compiler support a new [*key-value pair conversion*](#key-value-pair-conversions) within collection expressions to allow implicit conversions from an expression element of type `KeyValuePair<K1, V1>`, or a spread element with an iteration type of `KeyValuePair<K1, V1>` to the collection expression iteration type `KeyValuePair<K2, V2>`? | ||||||
|
||||||
### Concrete type for `I{ReadOnly}Dictionary<K, V>` | ||||||
|
||||||
What concrete type should be used for a dictionary expression with target type `IDictionary<K, V>`? | ||||||
|
||||||
Options include: | ||||||
1. Use `Dictionary<K, V>`, and state that as a requirement. | ||||||
2. Use `Dictionary<K, V>` for now, and state the compiler is free to use any conforming implementation. | ||||||
3. Synthesize an internal type and use that. | ||||||
|
||||||
What concrete type should be used for `IReadOnlyDictionary<K, V>`? | ||||||
|
||||||
Options include: | ||||||
1. Use a BCL type such as `ReadOnlyDictionary<K, V>`, and state that as a requirement. | ||||||
2. Use a BCL type such as `ReadOnlyDictionary<K, V>` for now, and state the compiler is free to use any conforming implementation. | ||||||
3. Synthesize an internal type and use that. | ||||||
|
||||||
We should consider aligning the decisions with the concrete types provided for collection expressions targeting mutable and immutable non-dictionary interfaces. | ||||||
|
||||||
### Question: Types that support both collection and dictionary initialization | ||||||
|
||||||
C# 12 supports collection types where the element type is some `KeyValuePair<,>`, where the type has an applicable `Add()` method that takes a single argument. Which approach should we use for initialization if the type also includes an indexer? | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
similar to above, the following is not legal today:
UseMyCollection(new(1));
. So i would expect the same to be true with CEs