Skip to content
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

[API Proposal]: allow collection expressions for 'ReadOnlyCollection<T>' #110161

Open
Sergio0694 opened this issue Nov 25, 2024 · 3 comments
Open
Assignees
Labels
api-ready-for-review API is ready for review, it is NOT ready for implementation area-System.Collections
Milestone

Comments

@Sergio0694
Copy link
Contributor

Sergio0694 commented Nov 25, 2024

Background and motivation

This proposal is about allowing collection expressions to be used to initialize ReadOnlyCollection<T> instances.
There are two main motivations for this:

  1. In lots of scenarios (eg. apps using MVVM), the type of the inner collection simply does not matter. You just want to expose a set of values from your viewmodel, so that the UI can bind to it. It's very common to want to expose them as a readonly type or interface, to enforce that nobody can modify contents directly. In such cases, you will have eg. a property initializer directly creating a ReadOnlyCollection<T> value from some array expression. Being able to use a collection expression would make such scenarios nicer and less verbose.
  2. In UWP/WinUI 3 scenarios using trimming and AOT with CsWinRT, there is a known limitation with collection expressions that make it so that targeting a readonly interface type (ie. IEnumerable<int> e = [1, 2, 3]) results in code that doesn't work at all with AOT. To work around this, ReadOnlyCollection<T> is a very easy and convenient choice: you can simply replace readonly interfaces for public properties in viewmodels with this, and that will make the code perfectly AOT compatible (because CsWinRT will be able to "see" the concrete type being used). Currently though, you cannot use collection expressions with it, meaning when you change properties to use this type, you'll be forced to switch to more verbose syntax with an object creation expression and a nested collection expression. It would be much nicer to just be able to use a collection expression directly.

I'd be happy to contribute this if it gets approved 🙂

Note

Extracted from #108457 (comment)

API Proposal

System.Collections.Generic
{
    public partial class CollectionExtensions
    {
        [EditorBrowsable(EditorBrowsableState.Never)]
        public static ReadOnlyCollection<T> CreateReadOnlyCollection<T>(params ReadOnlySpan<T> values);
    }
}

System.Collections.ObjectModel
{
    [CollectionBuilder(typeof(CollectionExtensions), "CreateReadOnlyCollection")]
    public partial class ReadOnlyCollection<T>;
}

Note

The contract of this builder method should make it clear that the returning type is guaranteed to be exactly ReadOnlyCollection<T>.

API Usage

public class MyViewModel : ObservableObject
{
    public ReadOnlyCollection<string> Names { get; } =
    [
        "Bob",
        "Alice"
    ];

    [ObservableProperty]
    public partial string? SelectedName { get; set; }
}
<ListView
    ItemsSource="{x:Bind ViewModel.Names}"
    SelectedItem="{x:Bind ViewModel.SelectedName, Mode=TwoWay}" />

Risks

No risk. This enables new syntax that couldn't be used before, and developers using that would not care about the concrete type of the inner list being used. Furthermore, ReadOnlyCollection<T> doesn't expose the inner list anyway, so it should not even matter at all in any case.

@Sergio0694 Sergio0694 added api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Collections labels Nov 25, 2024
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-collections
See info in area-owners.md if you want to be subscribed.

@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Nov 25, 2024
@eiriktsarpalis eiriktsarpalis removed the untriaged New issue has not been triaged by the area owner label Nov 25, 2024
@eiriktsarpalis eiriktsarpalis self-assigned this Nov 25, 2024
@eiriktsarpalis eiriktsarpalis added this to the 10.0.0 milestone Nov 25, 2024
@eiriktsarpalis eiriktsarpalis added api-ready-for-review API is ready for review, it is NOT ready for implementation and removed api-suggestion Early API idea and discussion, it is NOT ready for implementation labels Nov 25, 2024
@eiriktsarpalis
Copy link
Member

SGTM 👍

@Sergio0694
Copy link
Contributor Author

@eiriktsarpalis I just realized it would make sense to also do the same for:

  • ObservableCollection<T>
  • Collection<T>

Can I just update this proposal or should I create a new one?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-ready-for-review API is ready for review, it is NOT ready for implementation area-System.Collections
Projects
None yet
Development

No branches or pull requests

2 participants